Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: simple usage of JSON needed


This question is answered.


Permlink Replies: 16 - Last Post: Mar 21, 2016 1:57 AM Last Post By: Robert Triest
Allan Fernandes

Posts: 76
Registered: 9/30/00
simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 16, 2016 9:35 PM
When I create JSON thru a REST server (ISAPI) I get

{"result":["{\"books\":[{\"FLD_CODE\":\"1010\",\"FLD_NAME\":\"Allan\",\"FLD_MOBILE\":\"986701\",\"FLD_EMAILID\":\"allan@test.som\",\"FLD_ADDDATE\":\"01\/01\/16\",\"FLD_EDITDATE\":\"01\/01\/16\",\"FLD_TIMESCONNECTED\":\"99\",\"FLD_LASTJPG_VERSION\":\"1\"}]}"]}


When I create JSON thru a simple Delphi application I get

{"books":[{"FLD_CODE":"1010","FLD_NAME":"Allan","FLD_MOBILE":"986701","FLD_EMAILID":"allan@ssmic.om","FLD_ADDDATE":"01/01/16","FLD_EDITDATE":"01/01/16","FLD_TIMESCONNECTED":"99","FLD_LASTJPG_VERSION":"1"}]}


Parsing the latter output works and former gives Access violation

Logic used to Create JSON

var
  jStr:String ;
  o: TJSONObject;
  a: TJSONArray;
  book: TJSONObject;
  idx: integer;
  idy: integer;
begin
    o := TJSONObject.Create;
    a := TJSONArray.Create();
    o.AddPair('books',a);
    book := TJSONObject.Create;
    book.AddPair(TJSONPair.Create('FLD_CODE', '1010') );
    book.AddPair(TJSONPair.Create('FLD_NAME', 'Allan') );
    book.AddPair(TJSONPair.Create('FLD_MOBILE', '999999') );
    book.AddPair(TJSONPair.Create('FLD_EMAILID', 'allan@test.som') );
    book.AddPair(TJSONPair.Create('FLD_ADDDATE', '01/01/16' ) );
    book.AddPair(TJSONPair.Create('FLD_EDITDATE', '01/01/16' ) );
    book.AddPair(TJSONPair.Create('FLD_TIMESCONNECTED', '99') );
    book.AddPair(TJSONPair.Create('FLD_LASTJPG_VERSION', '1') );
    a.AddElement(book);
    memo1.text:=o.ToString ;

Logic used to Parse JSON

var
  jStr:String ;
  o: TJSONObject;
  a: TJSONArray;
  book: TJSONObject;
  idx: integer;
  idy: integer;
begin
  o := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(memo1.text),0) as TJSONObject;
  try
    a := TJSONArray(o.Get('books').JsonValue);
    for idx := 0 to pred(a.size) do begin
      book := TJSONObject(a.Get(idx));
      for idy := 0 to pred(book.Count) do begin
        ShowMessage( book.Pairs[idy].JsonString.ToString + ':' + book.Pairs[idy].JsonValue.ToString );
      end;
    end;
  finally
    o.Free;
  end;
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 12:49 AM   in response to: Allan Fernandes in response to: Allan Fernandes
Your can't parse the first string as it has been returned from the REST server.

http://salesforce.stackexchange.com/questions/85579/extra-backslash-in-json-string-when-exposing-webservice

The JSON String from the Delphi program is fine.
Allan Fernandes

Posts: 76
Registered: 9/30/00
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 6:16 AM   in response to: Allan Fernandes in response to: Allan Fernandes
But the whole purpose is to parse the string from my mobile apk.
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 7:13 AM   in response to: Allan Fernandes in response to: Allan Fernandes
But the whole purpose is to parse the string from my mobile apk.
You have to look at the Rest Server why it returns a JSON string with these slashes..
How do you retrieve this JSON string in Delphi?
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 7:47 AM   in response to: Allan Fernandes in response to: Allan Fernandes
In the JSON string all the double quotes " are escaped with slashes \"
The Delphi JSON parser can't parse strings that are escaped.
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 8:16 AM   in response to: Allan Fernandes in response to: Allan Fernandes
Allan Fernandes

Posts: 76
Registered: 9/30/00
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 10:10 AM   in response to: Allan Fernandes in response to: Allan Fernandes
I have used the Delphi wizard for the REST Server (CGI/ISAPI) only the JSON code is extra.
Please advice !!
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 10:38 AM   in response to: Allan Fernandes in response to: Allan Fernandes
You can try to remove the slashes in the string before you parse it.
When you sure that your original data doesn't contain a backslash...

strJSON:=StringReplace(strJSON,'\','',[rfReplaceAll]);

But you have to figure out why your RestServer transforms your JSON string with escape characters. (and adds an extra "result" JSONObject)
If you debug the server, has the JSON string already the escape chars before sending the data to the client?
Are you creating the JSON string on the Server in the same way as you showed in your first post?
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 10:46 AM   in response to: Robert Triest in response to: Robert Triest
What Delphi version are you using?

Read the commends here: (some have difficulties also..)

http://delphi.org/2013/09/delphi-xe5-mobile-rest-client-demo-source/
Allan Fernandes

Posts: 76
Registered: 9/30/00
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 11:12 AM   in response to: Allan Fernandes in response to: Allan Fernandes
Delphi Seattle
Does it have something to do with
TRESTClient, TRESTRequest, and TRESTResponse
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 12:55 PM   in response to: Allan Fernandes in response to: Allan Fernandes
Has the code something like:

result := jsonToObj(response.ResponseStr);

like

http://jamiei.com/blog/2013/01/simple-rest-client-for-delphi/
Allan Fernandes

Posts: 76
Registered: 9/30/00
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 17, 2016 9:08 PM   in response to: Allan Fernandes in response to: Allan Fernandes
No
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 18, 2016 1:11 AM   in response to: Allan Fernandes in response to: Allan Fernandes
Can you show the code from the Client where the "wrong" JSON string is returned from the Server?
You must have something like this , no?

response := request.Get;
if response.ResponseCode = 200 then
begin
  result := jsonToObj(response.ResponseStr);
  Self.doOnTodoReturned(result);
end else Self.doOnErrorStatus(response.ResponseCode, response.ResponseStr);
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 18, 2016 1:22 AM   in response to: Allan Fernandes in response to: Allan Fernandes
Maybe you use it like this:

var
  jValue:TJSONValue;
begin
  RESTRequest1.Execute;
  jValue:=RESTResponse1.JSONValue;
  MemoContent.Text:= jValue.ToString;
end;


See what the following is doing

var
  jString:String;
begin
  RESTRequest1.Execute;
  jString:=RESTResponse1.JSONText;
  MemoContent.Text:=jString;
end;

or
var
  jString:String;
begin
  RESTRequest1.Execute;
  jString:=RESTResponse1.Content;
  MemoContent.Text:=jString;
end;
Allan Fernandes

Posts: 76
Registered: 9/30/00
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 18, 2016 8:27 AM   in response to: Allan Fernandes in response to: Allan Fernandes
This is how I am receiving and parsing at the Client end

var
  jStr:String ;
  o: TJSONObject;
  a: TJSONArray;
  book: TJSONObject;
  idx: integer;
  idy: integer;
begin
 
  NetHTTPClient1.Get('http://localhost/RibbSrvISAPI/RibbSrvISAPI.dll/datasnap/rest/TServerMethods1/FetchRecord/9999999',RS) ;
  o := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(RS.DataString),0) as TJSONObject;
  try
    a := TJSONArray(o.Get('books').JsonValue);
    for idx := 0 to pred(a.size) do begin
      book := TJSONObject(a.Get(idx));
      for idy := 0 to pred(book.Count) do begin
        ShowMessage( book.Pairs[idy].JsonString.ToString + ':' + book.Pairs[idy].JsonValue.ToString );
      end;
    end;
  finally
    o.Free;
  end;
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 20, 2016 7:46 AM   in response to: Allan Fernandes in response to: Allan Fernandes
NetHTTPClient1.Get('http://localhost/RibbSrvISAPI/RibbSrvISAPI.dll/datasnap/rest/TServerMethods1/FetchRecord/9999999',RS) ;
RS.DataString

What I would do is :

Try to figure out what the JSON string is on the server Side before passing it to the Client.
If this is still the original String that can be parsed by the Delphi JSON routines then
the NetHTTPClient1 is modifying it with extra exscape characters. (I think so.. FireMonkey-Android-Linux)

Continue the development by modifying the RS.DataString received and delete the invalid characters.
If you parse other data you can espect other escape characters. (\n, \r, etc..)
http://tldp.org/LDP/abs/html/escapingsection.html
Maybe you find proper Delphi method to deal with all escape characters.

strJSON:=StringReplace(RS.DataString,'\n','',[rfReplaceAll]);
strJSON:=StringReplace(RS.DataString,'\r','',[rfReplaceAll]);
//etc..
//If only a single slash..
strJSON:=StringReplace(strJSON,'\','',[rfReplaceAll]);

idy: integer;
strJSON: String;
begin
  NetHTTPClient1.Get('http://localhost/RibbSrvISAPI/RibbSrvISAPI.dll/datasnap/rest/TServerMethods1/FetchRecord/9999999',RS) ;
  
  //Remove the slash
  strJSON:=StringReplace(RS.DataString,'\','',[rfReplaceAll]);
  //Remove also the "result"part
  strJSON:=StringReplace(strJSON,'{"result":["','',[rfReplaceAll]);
  //Remove the end "]}
  Delete(strJSON,Length(strJSON)-3,3);
  //obo alert..
 
  o := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(strJSON),0) as TJSONObject;
  try
    a := TJSONArray(o.Get('books').JsonValue);
    //..


While developing figure out how to get the unmodified JSON string from the server.

Analyse var RS.DataString are there other properies apart from DataString?
Using NetHTTPClient1.Post method? (By passing extra header info..)
Are there similar routines to (get/post) fetch data from the Server? (Indy idHTTP, FireMonkey compatible/multi platform routines?)

Edited by: Robert Triest on Mar 20, 2016 3:47 PM
Robert Triest

Posts: 687
Registered: 3/24/05
Re: simple usage of JSON needed
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 21, 2016 1:57 AM   in response to: Robert Triest in response to: Robert Triest
Are there similar routines to (get/post) fetch data from the Server? (Indy idHTTP, FireMonkey compatible/multi platform routines?)
Look at the TRESTClient, TRESTRequest and TRESTResponse components.
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Tutorial:_Using_the_REST_Client_Library_to_Access_REST-based_Web_Services
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02