Delphi HTTP Post JSON
delphi, indy, json
Solution
`HTTP1.Request.ContentEncoding` should be `HTTP1.Request.CharSet` instead. UTF-8 is a charset encoding, not a content encoding. And then make sure your JSON data is actually encoded to UTF-8 before posting it. If you are using ASCII characters, the `TStringStream` code you showed is fine. But if you are using non-ASCII Characters, you need to encode them, such as with `Utf8Encode()`. `TIdHTTP` does not encode `TStream` data, it is sent as-is.
Procedure Tformmaintestbed.btnJSONSendClick(Sender: TObject);
var
Json: string;
sResponse: string;
JsonToSend: TStringStream;
begin
Json := '{"auth": {"applicationId": "' + edApplication.text +
'","applicationPassword": "' + edpassword.text +
'","accountId": "' + edaccount.text +
'","userId": "' + edUser.text +
'"}}';
memoRequest.Text := Json;
JsonToSend := TStringStream.Create(Utf8Encode(Json)); // D2007 and earlier only
//in D2009 and later, use this instead:
//JsonToSend := TStringStream.Create(Json, TEncoding.UTF8);
try
HTTP1.Request.ContentType := 'application/json';
HTTP1.Request.CharSet := 'utf-8';
try
sResponse := HTTP1.Post(cbAddress.Text, JsonToSend);
except
on E: Exception do
ShowMessage('Error on request: '#13#10 + e.Message);
end;
finally
JsonToSend.Free;
end;
memoResponse.Text := sResponse;
end;
Alternatively:
Procedure Tformmaintestbed.btnJSONSendClick(Sender: TObject);
var
Json: string;
sResponse: string;
JsonToSend: TMemoryStream;
begin
Json := '{"auth": {"applicationId": "' + edApplication.text +
'","applicationPassword": "' + edpassword.text +
'","accountId": "' + edaccount.text +
'","userId": "' + edUser.text +
'"}}';
memoRequest.Text := Json;
JsonToSend := TMemoryStream.Create;
try
WriteStringToStream(JsonToSend, Json, enUTF8);
JsonToSend.Position := 0;
HTTP1.Request.ContentType := 'application/json';
HTTP1.Request.CharSet := 'utf-8';
try
sResponse := HTTP1.Post(cbAddress.Text, JsonToSend);
except
on E: Exception do
ShowMessage('Error on request: '#13#10 + e.Message);
end;
finally
JsonToSend.Free;
end;
memoResponse.Text := sResponse;
end;
Problem
I am sure I'm doing something wrong here. I've followed every example I can find on stackoverflow and still haven't gotten this to work in my environment. I'd love to update my controls and environment, but I'm currently locked in with what I have. I am using: - Delphi 7 - Indy 10.0.52 - ulkJSON.pas v1.07 I need to send this JSON to a URL: ``` "auth": { "applicationId": "appID", "applicationPassword": "pwd", "accountId": "acct", "userId": "dev" } ``` There isn't anything terribly crazy about this, but when I try to post my request I tend to get a message that the request was Closed Gracefully. CheckIsReadable in IDSocketHandle.pas has Handleallocated = false. I'm not sure what I've done wrong in configuring my IdHTTP, but it just won't work. I have tried examples from all these questions and several more, but none of these approaches seem to work for me: - Post JSON data to RESTful datasnap server from delphi client - Sending a JSON encoded object using Indy and Delphi - Delphi TIdhttp Post JSON? - Delphi TIdhttp Post JSON? - What’s the simplest way to call Http POST url using Delphi? Any tips would be greatly appreciated. The current variant looks like this: ``` procedure Tformmaintestbed.btnJSONSendClick(Sender: TObject); var code: Integer; sResponse: string; JsonToSend: TStringStream; begin JsonToSend := TStringStream.Create( '{"auth": {"applicationId": "' + edApplication.text + '","applicationPassword": "' + edpassword.text + '","accountId": "' + edaccount.text + '","userId": "' + edUser.text + '"}}'); try HTTP1.Request.ContentType := 'application/json'; HTTP1.Request.ContentEncoding := 'utf-8'; memoRequest.lines.clear; memoRequest.lines.add(JsonToSend); try sResponse := HTTP1.Post(cbAddress.text, JsonToSend); except on E: Exception do ShowMessage('Error on request: '#13#10 + e.Message); end; memoResponse.lines.clear; memoresponse.lines.add(sResponse); finally JsonToSend.Free(); end; end; ``` The idHTTP component is current set like this: ``` object HTTP1: TIdHTTP IOHandler = IdSSLIOHandlerSocketOpenSSL1 AuthRetries = 0 AuthProxyRetries = 0 AllowCookies = True HandleRedirects = True ProxyParams.BasicAuthentication = False ProxyParams.ProxyPort = 0 Request.ContentEncoding = 'utf-8' Request.ContentLength = -1 Request.ContentRangeEnd = 0 Request.ContentRangeStart = 0 Request.ContentRangeInstanceLength = 0 Request.ContentType = 'application/json' Request.Accept = 'application/json' Request.BasicAuthentication = False Request.UserAgent = 'Mozilla/3.0 (compatible; Indy Library)' HTTPOptions = [hoForceEncodeParams] Left = 564 Top = 120 end ```