#1 2022-07-08 07:59:21

bigheart
Member
Registered: 2014-08-01
Posts: 45

JSONToObject problem in mormot2

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

#2 2022-07-08 20:40:16

tbo
Member
Registered: 2015-04-20
Posts: 335

Re: JSONToObject problem in mormot2

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

#3 2022-07-08 22:15:42

bigheart
Member
Registered: 2014-08-01
Posts: 45

Re: JSONToObject problem in mormot2

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

#4 2022-07-09 05:47:27

bigheart
Member
Registered: 2014-08-01
Posts: 45

Re: JSONToObject problem in mormot2

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

#5 2022-07-09 06:46:06

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: JSONToObject problem in mormot2

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

Board footer

Powered by FluxBB