2017-12-21 7 views
2

Ich habe ein Problem mit der JSON-Zeichenfolge, die ich bekomme, wenn eine POST-Anfrage erhalten. Derzeit ist dies die Art, wie ich es gerade lese:Meine POST-Anfrage auf TIdHttpServer enthält seltsame Zeichen, JSON-Zeichenfolge

procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext; 
    ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); 
var 
    Stream : TStream; 
    S : string; 
begin 
    If ARequestInfo.Command = 'POST' then 
    begin 
    Stream := ARequestInfo.PostStream; 
    if assigned(Stream) then 
    begin 
     Stream.Position := 0; 
     S := UTF8ToAnsi(ReadStringFromStream(Stream)); 
    end; 
    end; 
end; 

ich ReadStringFromStream() allein versucht und mit UTF8ToAnsi() und AnsiToUTF8(), aber ich halte eine Zeichenfolge erhalten, die wie folgt aussieht:

‚[‘ # $ A # 9 '{' # $ A # 9 # 9 '"Test": "bb", "# $ A # 9 # 9" "Test": "aa"' # $ A # 9 '}' # $ A ']'

Ich weiß, es hat etwas mit Codierung zu tun, aber ich weiß nicht, wie es zu beheben ist.

Antwort

4

Sie wissen, dass die Raute (#) Zeichen ein Zeichenwert bezeichnet und dass der Dollar ($) Zeichen Hexadezimal-Werte, sind Sie bezeichnet. So bedeutet #$A Zeichen Dezimal 10, was bedeutet NewLine und #9 bedeutet Zeichen 9, die TAB Zeichen ist. Es gibt nichts Unerwartetes in der Rückkehrzeichenkette. Wenn Sie es in etwas einspeisen, das eine NewLine ohne eine vorangehende CarriageReturn versteht, wird es wahrscheinlich wie erwartet aussehen.

Der Debugger für exmple, verwendet die # -Syntax für Zeichen, die sonst visuell dargestellt werden kann nicht.

2

Die Daten, die Sie in Ihrem Beispiel gezeigt haben, sind vollkommen in Ordnung, wie von Tom B. erklärt. Sie betrachten die Zeichenfolge Daten im Debugger, #A ist ein Zeilenumbruch und #9 ist ein Tab-Zeichen, so dass die tatsächliche Zeichenfolge aussieht wie folgt:

 
[ 
    { 
     "test":"bb", 
     "test":"aa" 
    } 
] 

Welches ist gültig JSON.

jedoch die Art und Weise Sie die Daten lesen ist nicht in Ordnung, vor allem, wenn Sie eine Unicode-Version von Delphi verwenden (2009+). Sie passieren keinen Wert auf die AByteEncoding Parameter von ReadStringFromString(), so wird es das Stream-Bytes mit Indys Standard-Kodierung dekodieren, der 7-Bit-US-ASCII ist standardmäßig (siehe GIdDefaultTextEncoding Variable in der IdGlobal Einheit). JSON verwendet standardmäßig UTF-8, so dass Sie JSON beschädigen, wenn es Nicht-ASCII-Zeichen enthält. Die Verwendung von UTF8ToAnsi() nach der Tat wird das nicht beheben.

Der Code sollte wie diese stattdessen aussehen:

procedure TForm1.IdHTTPServer1CommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); 
var 
    Stream : TStream; 
    S : string; 
begin 
    If ARequestInfo.CommandType = hcPOST then 
    begin 
    Stream := ARequestInfo.PostStream; 
    if Assigned(Stream) then 
    begin 
     S := ReadStringFromStream(Stream, -1, IndyTextEncoding_UTF8); 
    end 
    end 
end; 

Das Indy die Stream-Bytes als UTF-8 in UTF-16 zu entschlüsseln sagt, dann die decodierte Zeichenfolge zurück (wenn Sie ein Nicht-Unicode verwenden Version von Delphi werden die UTF-16-Daten beim Beenden in ANSI konvertiert, wobei der optionale Parameter ADestEncoding (ReadStringFromStream()) zu berücksichtigen ist.

+0

Hallo, danke für deine Antwort. Es besagt, dass ReadStringFromStream mit diesen Parametern nicht überladen wird. Ich benutze Delphi Berlin 10.1 btw – John

+0

eigentlich nach dem Versuch, den Stream auch mit den # Zeichen zu lesen, es funktioniert immer noch und löst keine Ausnahmen aus. – John

+0

@John mein Schlechter, ich habe einen Parameter vergessen. Es ist jetzt behoben –