You are not logged in.
Pages: 1
Hello.
I try to convert json to delphi nested object like below:
TOrm1 = class(TOrm)
FStr: string;
published
property str: string read FStr write FStr;
end;
TMyClass = class
Fb: Boolean;
Fc: TOrm1;
published
property b1: Boolean read Fb write Fb;
property c1 : Torm1 read Fc write Fc;
end;
....
LMyClass := TMyClass.Create;
Lutf8 := '{"b1": true, "c1": {"str": "abcd"}}';
JsonToObject(LMyClass, Pointer(LUtf8), LValid, nil, JSONToOBJECT_TOLERANTOPTIONS);
ShowMessage(LMyClass.c1.str); //<=== here
And i have at Showmessage function.
Result is LMyClass.c1.str = ''
Could anyone please some advise to me how to use JSONToObject() with nested class?
Thanks in advance.
Last edited by bigheart (2022-07-08 08:06:21)
Offline
Delphi 11.1, mORMot 3547
This works for me:
type
TOrm1 = class(TOrm)
private
FStr: string;
published
property Str: string read FStr write FStr;
end;
TMyClass = class
private
Fb: Boolean;
Fc: TOrm1;
published
property b1: Boolean read Fb write Fb;
property c1 : TOrm1 read Fc write Fc;
end;
var
LMyClass: TMyClass;
LUtf8: RawUtf8;
LValid: Boolean;
begin
LMyClass := TMyClass.Create;
try
LUtf8 := '{"b1": true, "c1": {"str": "abcd"}}';
JsonToObject(LMyClass, Pointer(LUtf8), LValid, Nil, JSONToOBJECT_TOLERANTOPTIONS);
ShowMessage(LMyClass.c1.str);
finally
LMyClass.Free;
end;
end;
PS: With Delphi 11.1, your source code calls the constructor of the class TOrm1, but not the destructor. The hint from Arnaud is the solution.
With best regards
Thomas
Last edited by tbo (2022-07-09 10:53:27)
Offline
My circumstance is win10, XE5 and mormot2 3606.
And the result is LMyClass.c1.str = ''.
I don't understand what is problem.
Last edited by bigheart (2022-07-08 22:16:18)
Offline
When debug, i got AV at function GetJsonPropName() of mormot.core.json.
P^ value is '"'
I think P^ should be instance pointer but it is string value.
function GetJsonPropName(var Json: PUtf8Char; Len: PInteger;
NoJsonUnescape: boolean): PUtf8Char;
...
if Len <> nil then
Len^ := P - Name;
P^ := #0; // ensure Name is #0 terminated <===== AV at here
repeat
inc(P);
if P^ = #0 then
exit;
until P^ = ':';
Json := P + 1;
result := Name;
end;
Is there anyone to give me a hand?
Offline
Try with
TMyClass = class(TSynAutoCreateFields)
because your plain TClass does not instantiate the nested TOrm
and look at the documentation, e.g. at https://synopse.info/files/html/Synopse … #TITLE_621.
And you have an access violation problem because you use pointer() on a constant string, and, as documented, JsonToObject() parses it in place, so it tries to write #0 within the constant memory, so it raises a GPF.
Use the overloaded function which makes a private copy, i.e. use RawUtf8 and not PUtf8Char.
Offline
Pages: 1