#1 2013-02-27 11:10:47

chapa
Member
Registered: 2012-04-30
Posts: 117

ObjectToJSON <-> JSONToNewObject error

Consider having classes defined like this:

TMyContainedClass = class
(...)
published
  property Name: RawUTF8 read write;
end;
TMyContainedClassList = TObjectList;

TMyClass = class
(...)
published
  property Name: RawUTF8 read write;
  property MyContainedClassList: TMyContainedClassList read write;
end;
TMyClassList = TObjectList;

Having one objects in the lists I do serialization to Json string using ObjectToJSON().
As far as I see, instance of TMyClassList is correctly serialized.

Unfortunately, trying to de-serialize using TObjectList(JSONToNewObject(jsonPtr, valid)) set valid to False and returns nil

Is it correct behavior?

Offline

#2 2013-02-27 12:00:28

chapa
Member
Registered: 2012-04-30
Posts: 117

Re: ObjectToJSON <-> JSONToNewObject error

Ok, it seems not well formatted JSON for JSONToNewObject, as it does not start with '{'.

Tried with JSONToObject, same valid False result.
TMyClass instance created well and added to MyClassList. But new instance created contains nil for MyContainedClassList field and processing json fails.

Workaround is to manually create MyContainedClassList field on AfterConstruction, so nasted call to JSONToObject will have valid ObjectInstance as parameter.

Offline

#3 2013-02-27 14:22:44

chapa
Member
Registered: 2012-04-30
Posts: 117

Re: ObjectToJSON <-> JSONToNewObject error

Proposal for ClassInstanceCreate(aClass: TClass)

I see it checks whenever aClass is TSQLRecord, TInterfacedCollection, TCollection, ... in order proper class constructor to be called upon object creation.
It will be good TObjectList to be named there, and TObjectList constructor to be called, as it set FOwnsObjects to True. This is default behavior for TObjectList.
This will prevent memory leaks when TObjectList transmitted as a interface service parameter. Parameters are auto-freed, but one have to cycle all contained TObjectList in parameter and manually set OwnsItems to True.
Other case - unexpected memory leaks.

Offline

#4 2013-02-27 14:34:01

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

Re: ObjectToJSON <-> JSONToNewObject error

There is already the oObjectList internal kind of class within mORMot.pas.

Do you use the latest 1.18 version from http://synopse.info ?

Offline

#5 2013-02-27 14:37:05

chapa
Member
Registered: 2012-04-30
Posts: 117

Re: ObjectToJSON <-> JSONToNewObject error

Yes, latest sources I am using.

Offline

#6 2013-03-12 13:32:17

anvo
Member
Registered: 2013-03-12
Posts: 1

Re: ObjectToJSON <-> JSONToNewObject error

I've got the same problem (using 1.18). I want to read a complex JSON-String, which looks like:

{
        "ClassName":"TMyClass",
        "Name":"MainContainer",
        "MyContainedClassList":
        [
                {
                        "ClassName":"TMyClass",
                        "Name":"Container",
                        "MyContainedClassList":
                        [
                                {
                                        "ClassName":"TMyContainedClass",
                                        "Name": "Name0",
                                },
                                {
                                        "ClassName":"TMyContainedClass",
                                        "Name": "Name1",
                                },
                        ]
                }
        ]
}

The first object of TMyClass ("MainContainer") is created by myself before executing the JSONtoObject-method. The second one ("Container") should be created by the JSONtoObject-method.

In my opinion the problem is in the mORMot.pas:26129

result := aClass.Create

There the constructor of TMyClass should be called to create the MyClass object with its TMyContainedClassList. But it never happens. A base class with a virtual constructor is necessary to do that. aClass itself is a TClass object (class of TObject) which hasn't got a virtual constructor.

Last edited by anvo (2013-03-12 13:34:10)

Offline

#7 2013-03-12 13:40:25

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

Re: ObjectToJSON <-> JSONToNewObject error

Did you register your class via TJSONSerializer.RegisterClassForJSON() ?

Other possibilitites:
- You can have a virtual constructor if you inherit from TInterfacedCollection - which is handled as expected by function ClassInstanceCreate().
- Or you can register your collection class/item pair via TJSONSerializer.RegisterCollectionForJSON().

Offline

#8 2013-04-12 09:56:52

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

Re: ObjectToJSON <-> JSONToNewObject error

TObjectList problem fixed by http://synopse.info/fossil/info/6e1fd07333

Thanks for the input!

Offline

Board footer

Powered by FluxBB