Fabian1648 2 Posted September 29, 2020 I'm trying to extract data from a REST response with Delphi 10.3.3. RESTResponse1.ContentType indicates 'application/json' RESTResponse1.JSONText give a JSON answer I use a code coming from the Delphi sample RESTDEMOS Quote var LValues: TJSONArray; LJson: TJSONObject; LTempSensorName: string; LValue: TJsonValue; Quote LJson := RESTRequest.Response.JSONValue as TJSONObject; LValues := LJson.Values['values'] as TJSONArray; for LValue in LValues do begin // the sensor values are not objects unfortunately, but arrays of strings if (LValue as TJSONArray).Items[0].Value = LTempSensorName then begin LTemp := StrToInt((LValue as TJSONArray).Items[1].Value) / 100; Lbl_Temperature.Caption := Format('%3.0f°F', [LTemp]); break; end; end; And it ends with a "Transtyping error" on the first line "LJson := RESTRequest.Response.JSONValue as TJSONObject;". I can't even retrieve the REST response in a variable of type TJSONObject as TJSONObject;!!! Does anyone have a sample code that works? Is this a known bug in version 10.3.3? Thanks for your answers Share this post Link to post
Arnaud Bouchez 407 Posted September 29, 2020 Could you put a reproducible sample somewhere, e.g. as gist? Share this post Link to post
Fabian1648 2 Posted September 29, 2020 The problem seems to be due to the fact that the JSON format sent by the server is not compatible with "JSON made in Delphi"! I found an example that works with code and "JSON that fits" and the JSON has "\" in it that I haven't seen in any example JSON file. Quote const response = '{"result":["[{\"email\":\"XXX@gmail.com\",\"regid\":\"12312312312312312313213w\"},'+ '{\"email\":\"YYYY@gmail.com\",\"regid\":\"AAAAAAA\"}]"]}'; response_bis = '{"result":["[{"email":"XXX@gmail.com","regid":"12312312312312312313213w"},'+ '{"email":"YYYY@gmail.com","regid":"AAAAAAA"}]"]}'; var LResult: TJSONArray; LJsonResponse: TJSONObject; ja: TJSONArray; jv: TJSONValue; begin LJsonResponse := TJSONObject.ParseJSONValue(response) as TJSONObject; LResult := LJsonResponse.GetValue('result') as TJSONArray; ja := TJSONObject.ParseJSONValue(LResult.Items[0].Value) as TJSONArray; for jv in ja do begin memo1.Lines.Add(jv.GetValue<string>('email')); memo1.Lines.Add(jv.GetValue<string>('regid')); end; end; The same code processing a JSON from different test servers via REST gives an " Transtyping Error" on the line "LJSONResponse:= TJSONObject.ParseJSONValue(response) as TJSONObject;". The same code with the "JSON that fits" without the "\" (=response_bis) and we end up with an "Access Violation error" ... Delphi can parse a JSON file or only a JSON file using a specific Delphi format??? Share this post Link to post
Lars Fosdal 1792 Posted September 29, 2020 Your Json example consists of an array containing a single string that appear to contains the Json you actually want. { "result": ["[{\"email\":\"XXX@gmail.com\",\"regid\":\"12312312312312312313213w\"},{\"email\":\"YYYY@gmail.com\",\"regid\":\"AAAAAAA\"}]"] } That is why you see the \" escape for each double quote in the actual Json. If you removed the outer array and string quotes, you would see this, but that is not valid Json, as there is no left side reference to that array. { [{ "email": "XXX@gmail.com", "regid": "12312312312312312313213w" }, { "email": "YYYY@gmail.com", "regid": "AAAAAAA" }] } For it to be valid, it would need to look like this. { "result": [{ "email": "XXX@gmail.com", "regid": "12312312312312312313213w" }, { "email": "YYYY@gmail.com", "regid": "AAAAAAA" }] } Somewhere in the process, that Json has been badly mangled. Why is there an outer array and string quotes around the Json you want? The question is: did it happen on the server side, or on the client side? Share this post Link to post
Fabian1648 2 Posted September 30, 2020 I'm giving the benefit of the solution I found to solve my Transtyping error problem. I confirm that the problem comes from the format of the JSON response sent by the server. The JSON returned does not have a "{"result":[...]}" format but "{[...]}". Solution: 1. I retrieve the JSON sent by the server by a "str:=RESTResponse1.JSONText;". 2. I adapt the string: "{[...]}" becomes "{"result":[...]}". 3. I transform the modified string into a TJSONValue by a "JSONValue := TJSonObject.ParseJSONValue(str);". (Eureka! there is no more "Transtyping error") 4. I retrieve the values in JSONValue by code like "str1 := JsonValue.GetValue<string>('results[0].header');". Thanks to the various contributors who offered me their help. Share this post Link to post
Lars Fosdal 1792 Posted September 30, 2020 I.e. that server does not produce valid Json. Share this post Link to post