I'm trying to use Rest.JSON in this example below but I'm losting the same name property parent-child class (Items). Just create a new vcl application in Delphi XE and paste this code to see what's happening:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Rest.JSON;
type
TParentItemsClass = class
strict private
fID: integer;
fName: string;
public
property ID: integer read fID write fID;
property Name: string read fName write fName;
end;
TParentClass = class
strict private
fID: integer;
fName: string;
fItems: TParentItemsClass;
public
constructor Create;
property ID: integer read FID write fID;
property Name: string read FName write fName;
property Items: TParentItemsClass read FItems write fItems;
end;
TChildItemsClass = class(TParentItemsClass)
strict private
fSomeField: integer;
public
property SomeField: integer read fSomeField write fSomeField;
end;
TChildClass = class(TparentClass)
strict private
fItems: TChildItemsClass;
public
constructor Create;
property Items: TChildItemsClass read fItems write fItems;
end;
TForm1 = class(TForm)
private
{ Private declarations }
public
constructor Create(AOwner: TComponent); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TParentClass }
{ TParentClass }
constructor TParentClass.Create;
begin
fItems:= TParentItemsClass.Create;
end;
{ TChildClass }
constructor TChildClass.Create;
begin
fItems:= TChildItemsClass.Create;
end;
{ TForm1 }
constructor TForm1.Create(AOwner: TComponent);
var AChild, BChild: TChildClass;
begin
inherited;
AChild:= TChildClass.Create;
AChild.Items.ID:= 1;
AChild.Items.SomeField:= 2;
AChild.Items.Name:= 'abc';
BChild:= TJSON.JsonToObject<TChildClass>(TJSON.ObjectToJsonString(AChild));
Application.MessageBox(PWideChar(TJSON.ObjectToJsonString(AChild)+#13+#13+TJSON.ObjectToJsonString(BChild)), '', mb_ok);
end;
end.
This results in:
AChild:
{"items":{"someField":2,"iD":1,"name":"abc"},"iD":0,"name":"","items":null}
BChild
{"items":null,"iD":0,"name":"","items":null}
How to avoid this? I need that BChild JSON looks like AChild JSON
Your class TParentClass
and TChildClass
both have a private field fItems
. If you watch the JSON your code outputs closely, you have already posted the answer in your question!
Look at the value of AChild
:
{
"items": {
"someField": 2,
"iD": 1,
"name": "abc"
},
"iD": 0,
"name": "",
"items": null
}
See how it contains items
twice. This is what gets used when you marshal your JSON string back to BChild
. And this is certainly not what you want.
A quick workaround would be renaming your internal field TChildClass.fItems
to, for example TChildClass.fItems_
.