Ali Ahmadi Ali Ahmadi - 3 months ago 54
JSON Question

IdHttp : how to deal with json request and response

I have encountered a few sites that uses

JSON
for request and response

I come across two types :

1-
application/x-www-form-urlencoded
as request and return a response
application/json
content type

2-
application/json
content type for both request and response

in
type 1
i tried changing the the response content type using

mIdHttp.Response.ContentType := 'application/json';


but using http analyzer i can see that it doesn't change and its still
text/html


now i do not know if the problem is with the fact that i can't change content type or not but i do not know how to deal with
json
!

a few question regarding
json
:

1- do i have to encode json data when posting ? how ?

2- how can i parse the json response code ? how to get it ? does it need some kind of encode or special convertion ?

3- what kind of idhttp setting for json changes with each site and needs configuring ?

I understand my questions sound a bit general, but all the other questions are very specific and don't explain the basics when dealing with
'application/json'
content type.

Edit 1 :

thanks to Remy Lebeau answer i was able to successfully work with
type 1


but i still have trouble sending
JSON
request, can someone please share an working example, this is one of the sites posting information please use this for your example :

enter image description here

One important note : this particular site's post and request content are exactly like each other ! and it baffles me because at the site, i specify an
start date
and an
end date
then click on a
folder like icon
and this
post
is sent (the one you can see above), and the
result
should be
links
(and it is) but instead of appearing only in
request content
they also appear in
post
! (also i'm trying to get the links but at the
post
the links, the thing i want, are also being sent, how can i post something i don't have !!?)

just for more clarity here is the place i fill the date and the icon i mentioned :

enter image description here

Answer

You cannot specify the format of the response, unless the requested resource offers an explicit input parameter or dedicated URL for that exact purpose (ie, to request a response be sent as html, xml, json, etc). Setting the TIdHTTP.Response.ContentType property is useless. It will be overwritten by the actual Content-Type header of the response.

To send JSON in a request, you must post it as a TStream, like TMemoryStream or TStringStream, and set the TIdHTTP.Request.ContentType as needed, eg:

var
  ReqJson: TStringStream;
begin
  ReqJson := TStringStream.Create('json content here', TEncoding.UTF8);
  try
    IdHTTP1.Request.ContentType := 'application/json';
    IdHTTP1.Post(URL, ReqJson);
  finally
    ReqJson.Free;
  end;
end;

To receive JSON, TIdHTTP can either

  1. return it as a String (decoded using a server-reported charset):

    var
      ReqJson: TStringStream;
      RespJson: String;
    begin
      ReqJson := TStringStream.Create('json content here', TEncoding.UTF8);
      try
        IdHTTP1.Request.ContentType := 'application/json';
        RespJson := IdHTTP1.Post(URL, ReqJson);
      finally
        ReqJson.Free;
      end;
      // use RespJson as needed...
    end;
    
  2. write the raw bytes to an output TStream of your choosing:

    var
      ReqJson: TStringStream;
      RespJson: TMemoryStream;
    begin
      RespJson := TMemoryStream.Create;
      try
        ReqJson := TStringStream.Create('json content here', TEncoding.UTF8);
        try
          IdHTTP1.Request.ContentType := 'application/json';
          RespJson := IdHTTP1.Post(URL, ReqJson, RespJson);
        finally
          ReqJson.Free;
        end;
        RespJson.Position := 0;
        // use RespJson as needed...
      finally
        RespJson.Free;
      end;
    end;
    

The HTTP response code is available in the TIdHTTP.Response.ResponseCode (and TIdHTTP.ResponseCode) property.