Why does TJson.ObjectToJsonObject / ObjectToJsonString represent the record fields as a JSON array?
There is an inconsistency in how SuperObject and TJson.ObjectToJsonObject represent certain parts of a class (i.e. record fields). Suppose you have the following piece of code:
Uses rest.json, superobject;
type
TSimplePersonRec = record
FirstName: string;
LastName: string;
Age: byte;
end;
TSimplePerson = class
protected
FPersonRec: TSimplePersonRec;
public
property personRecord: TSimplePersonRec read FPersonRec write FPersonRec;
end;
// ...
{ Public declarations }
function toJson_SO(simplePerson: TSimplePerson): string;
function toJson_Delphi(simplePerson: TSimplePerson): string;
// ...
function TForm1.toJson_Delphi(simplePerson: TSimplePerson): string;
begin
result := tjson.Format(TJson.ObjectToJsonObject(simplePerson));
end;
function TForm1.toJson_SO(simplePerson: TSimplePerson): string;
var
so: ISuperObject;
ctx: TSuperRttiContext;
begin
ctx := TSuperRttiContext.Create;
try
so := ctx.AsJson<TSimplePerson>( simplePerson );
finally
ctx.Free;
end;
result := so.AsJSon(true, true);
end;
// ...
procedure TForm1.Button3Click(Sender: TObject);
var
spr: TSimplePersonRec;
sp: TSimplePerson;
begin
spr.FirstName := 'John';
spr.LastName := 'Doe';
spr.Age := 39;
sp := TSimplePerson.Create;
sp.personRecord := spr;
memo1.Lines.Add(#13'--- SuperObject ---'#13);
memo1.Lines.Add(toJson_SO(sp));
memo1.Lines.Add(#13'--- Delphi ---'#13);
memo1.Lines.Add(toJson_Delphi(sp));
end;
Output:
--- SuperObject ---
{
"FPersonRec": {
"LastName": "Doe",
"Age": 39,
"FirstName": "John"
}
}
--- Delphi ---
{
"personRec":
[
"John",
"Doe",
39
]
}
What is the reason Delphi represents records as JSON array? Is there a community standard or proposal leading to this?
Note: It's more natural for me to represent records using {key: value} notation instead of an array. Not knowing which key name matters can have strange results when deserializing. For example, during deserialization, I could pass in a new class with the same layout, containing an entry with a different memory layout. In this case, the values will be randomly assigned or AV may occur?
UPDATE: I am using Delphi XE7. Also I found this from json.org:
JSON is built on two structures:
- A collection of name / value pairs. In different languages, this is implemented as an object, record, structure, dictionary, hash table, keyed list, or associative array.
- An ordered list of values. In most languages, this is implemented as an array, vector, list, or sequence.
So, probably the question is, is this a bug in the TJson block?
source to share
Delphi output is legal JSON. Internally REST.TJson
hardcoded to marshal the entry as a JSON array. It's just how it's implemented, it's by design, not a bug. It's just a different way of presenting data. SuperObject prefers to be more explicit. It's okay too. Two different implementations, two different views. The JSON specification allows both.
source to share