Mariusz Pluciennik
Mariusz Pluciennik

Reputation: 107

Can't deserialize valid JSON using system.json

I write some code (rest server) that produce for me data in JSON format. When I use it in PHP it works fine, JSON is valid, everything is ok. When I use it in Delphi nothing works.

When I search internet I found:

desearilizing JSON using SuperObject

but that method returns empty strings for me.

I want to use that JSON elements as array (eg. JSONValue.items[i]).

I'm using Delphi XE7 System.JSON and don't want to use superobject or any others libraries.

How use it as array?

I paste my code that generates JSON:

var
  qry: TfdQuery;
  FieldsObj: TJSONObject;
  FieldNameArray: TJSONArray;
  I: Integer;
  DataObj: TJSONObject;
  DataRows: TJSONArray;
  RowFields: TJSONArray;
  tablename:string;
begin
  tablename:='produkt';
  qry := TfdQuery.Create(Self);
  qry.SQL.Text := 'select * from produkt where (id ='''+ProductID+''')';
  qry.Connection := FDConnection1;
  qry.Open;
  FieldsObj := TJSONObject.Create;
  FieldNameArray := TJSONArray.Create;
  for I := 0 to qry.FieldCount - 1 do
    FieldNameArray.Add(qry.Fields[I].FieldName);
  FieldsObj.AddPair(TableName, FieldNameArray);
  DataObj := TJSONObject.Create;
  DataRows := TJSONArray.Create;
  qry.First;
  while not qry.Eof do
  begin
    RowFields := TJSONArray.Create;
    for I := 0 to qry.FieldCount - 1 do
      RowFields.Add(qry.Fields[I].AsString);
    DataRows.Add(RowFields);
    qry.Next;
  end;
  DataObj.AddPair('data', DataRows);
  Result := TJSONArray.Create(FieldsObj, DataObj);
  qry.Free;

And this is the result:

{
    "ProductID": "1",
    "result": [{
        "produkt": ["id", "parent_id", "full_name", "opcja_1", "opcja_2", "opcja_3", "opcja_4", "opcja_5", "opcja_6", "opcja_7", "opcja_8", "opcja_9", "opcja_10", "opcja_11", "opcja_12", "field_address1", "field_address2", "quantity", "opis", "zdjecie1", "zdjecie2", "zdjecie3", "samples", "link_stable0", "link_stable1", "link_stable2", "price1", "price2", "price3"]
    }, {
        "data": [
            ["1", "1", "name", "1", "1", "1", "1", "0", "0", "0", "0", "0", "0", "0", "12", "10", "20", "1,2", "description of product", "http://www.vphosted.com/e6=0", "photo link2", "photo link 3", "sample project file link", "link option", "10", "link", "10", "link", "10"]
        ]
    }]
}

Upvotes: 0

Views: 522

Answers (1)

Dsm
Dsm

Reputation: 6013

This would produce JSON more in the format that I would expect:

var
  qry: TfdQuery;
  FieldsObj: TJSONObject;
  //FieldNameArray: TJSONArray;
  I: Integer;
  DataObj: TJSONObject;
  FieldObj: TJSONObject;
  DataRows: TJSONArray;
  RowFields: TJSONArray;
  tablename:string;
begin
  tablename:='produkt';
  qry := TfdQuery.Create(Self);
  qry.SQL.Text := 'select * from produkt where (id ='''+ProductID+''')';
  qry.Connection := FDConnection1;
  qry.Open;
  FieldsObj := TJSONObject.Create;
  //FieldNameArray := TJSONArray.Create;
  //for I := 0 to qry.FieldCount - 1 do
  //  FieldNameArray.Add(qry.Fields[I].FieldName);
  //FieldsObj.AddPair(TableName, FieldNameArray);
  DataObj := TJSONObject.Create;
  DataRows := TJSONArray.Create;
  qry.First;
  while not qry.Eof do
  begin
    RowFields := TJSONArray.Create;
    for I := 0 to qry.FieldCount - 1 do
    begin
      FieldObj := TJSONObject.Create;
      FieldObject.AddPair(qry.Fields[I].FieldName, qry.Fields[I].AsString));
      RowFields.Add( FieldObj );
    end;
    DataRows.Add(RowFields);
    qry.Next;
  end;
  DataObj.AddPair('data', DataRows);
  Result := TJSONArray.Create(FieldsObj, DataObj);
  qry.Free;

If you know the record structure, though, I would prefer to use REST.JSON, which I am pretty sure ships with XE7 and is much simpler to use. You just create your object structure, create an instance of that structure, populate it with your field values and use

TJSON.ObjectToJsonString( fObject )

to create your string and

  iObject := TJSON.JsonToObject<TMyObject>( pTransferString );

to get your object back.

If you want a more complete example using this method, let me know and I will post.

Upvotes: 1

Related Questions