#1 2015-06-05 17:46:38

turrican
Member
From: Barcelona
Registered: 2015-06-05
Posts: 94
Website

Stucked at deserialization

Hi,

I'm very new with mORMot Framework. I am looking for the best Delphi's ORM and I found this framework, a piece of wonderful code. Thanks for your great work.

Today I was playing with Object to JSON Serialization and went very well, but i try to deserialize the JSON again with bad result.

There is my testing code :

program JSONSerializer;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Classes,
  mORMOt,
  SynCommons,
  System.Generics.Collections;

type

  TMyCollection = class(TCollection)
    public
      destructor Destroy; override;
      function Serialize: string;
      procedure Searlizetofile(tofile: string);
  end;

  TSubItem = class(TCollectionItem)
    private
      ftext: string;
    published
      property Text: string read ftext write ftext;
  end;

  TItem = class(TCollectionItem)
    private
      fname: string;
      fsubitems: TCollection;
    published
      property Name: string read fname write fname;
      property SubItems: TCollection read fsubitems write fsubitems;
    public
      destructor Destroy; override;
  end;

destructor TMyCollection.Destroy;
var
  Item: TCollectionItem;
begin
  for Item in Self do Item.Free;
end;

function TMyCollection.Serialize: string;
begin
  TJSONSerializer.RegisterClassForJSON(Self.ClassType);
  Result:=ObjectToJSON(Self);
end;

procedure TMyCollection.Searlizetofile(tofile: string);
begin
  TJSONSerializer.RegisterClassForJSON(Self.ClassType);
  ObjectToJSONFile(Self,tofile);
end;

destructor TItem.Destroy;
begin
  if Assigned(fsubitems) then SubItems.Free;
end;

var
 Collection1: TMyCollection;
 Item: TItem;
 Subitem: TSubItem;
 X: Integer;
 Y: Integer;

begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
    Writeln(GetTickCount64.ToString);
    Collection1:=TMyCollection.Create(TItem);
    for X := 1 to 3 do
    begin
      Item:=TItem(Collection1.Add);
      Item.Name:='Iteration ' + X.ToString;
      Item.SubItems:=TCollection.Create(TSubItem);
      for Y:= 1 to 500 do
      begin
        Subitem:=TSubItem(Item.SubItems.Add);
        Subitem.Text:='Subitem ' + Y.ToString;
      end;
    end;
    Collection1.Searlizetofile('.\file1.txt');
    Collection1.Free;
    Collection1:=TMyCollection.Create(TItem);
    JSONFileToObject('.\file1.txt', Collection1, nil);
    Writeln(Collection1.Serialize);
    Writeln(GetTickCount64.ToString);
    Readln;
  except
    on E: Exception do
    Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Serialization does all ok.

What i'm doing wrong?

Thanks! smile

Offline

#2 2015-06-06 08:33:18

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

Re: Stucked at deserialization

Due to the current implementation pattern of the TCollection type in Delphi, it was not possible to implement directly this kind of values.

In fact, the TCollection constructor is defined as such:

constructor Create(ItemClass: TCollectionItemClass);

And, on the server side, we do not know which kind of TCollectionItemClass is to be passed. Therefore, the TServiceFactoryServer is unable to properly instantiate the object instances, supplying the expected item class.

The framework propose two potential solutions:
- You can let your collection class inherit from the new TInterfacedCollection type;
- You can call the TJSONSerializer.RegisterCollectionForJSON() method to register the collection type and its associated item class.

See http://synopse.info/files/html/Synopse% … ml#TITL_55

Offline

#3 2015-06-08 07:56:21

turrican
Member
From: Barcelona
Registered: 2015-06-05
Posts: 94
Website

Re: Stucked at deserialization

Thanks ab,

What kind of class did you recommend me to serialize/deserialize complex objects?

Offline

#4 2015-06-08 08:17:48

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

Re: Stucked at deserialization

If you can, you could use records and dynamic arrays.
They are perfect containers.

Otherwise, if you need plain collections, you may use TCollection, and call the TJSONSerializer.RegisterCollectionForJSON() method.
It would let your collection not be tied to mORMot's TInterfacedCollection type.

Offline

#5 2015-06-09 11:58:52

turrican
Member
From: Barcelona
Registered: 2015-06-05
Posts: 94
Website

Re: Stucked at deserialization

Hi ab,

ab wrote:

- You can call the TJSONSerializer.RegisterCollectionForJSON() method to register the collection type and its associated item class.

This works ok with serialization.

But here at unserialization crash :

    Collection1:=TMyCollection.Create(TItem);
    JSONFileToObject('.\file1.txt', Collection1, nil);

It's unable to parse JSON again.

My edited code :

program JSONSerializer;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Classes,
  mORMOt,
  SynCommons,
  System.Generics.Collections;

type

  TSubItem = class(TCollectionItem)
    private
      ftext: string;
    published
      property Text: string read ftext write ftext;
  end;

  TItem = class(TCollectionItem)
    private
      fname: string;
      fsubitems: TCollection;
    published
      property Name: string read fname write fname;
      property SubItems: TCollection read fsubitems write fsubitems;
    public
      destructor Destroy; override;
  end;

  TMyCollection = class(TCollection)
    public
      destructor Destroy; override;
      function Serialize: string;
      procedure Searlizetofile(tofile: string);
  end;

destructor TMyCollection.Destroy;
var
  Item: TCollectionItem;
begin
  for Item in Self do Item.Free;
end;

function TMyCollection.Serialize: string;
begin
  TJSONSerializer.RegisterCollectionForJSON(TMyCollection, TItem);
  Result:=ObjectToJSON(Self);
end;

procedure TMyCollection.Searlizetofile(tofile: string);
begin
  TJSONSerializer.RegisterCollectionForJSON(TMyCollection, TItem);
  ObjectToJSONFile(Self,tofile);
end;

destructor TItem.Destroy;
begin
  if Assigned(fsubitems) then SubItems.Free;
end;

var
 Collection1: TMyCollection;
 Item: TItem;
 Subitem: TSubItem;
 X: Integer;
 Y: Integer;

begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
    Writeln(GetTickCount64.ToString);
    Collection1:=TMyCollection.Create(TItem);
    for X := 1 to 3 do
    begin
      Item:=TItem(Collection1.Add);
      Item.Name:='Iteration ' + X.ToString;
      Item.SubItems:=TCollection.Create(TSubItem);
      for Y:= 1 to 500 do
      begin
        Subitem:=TSubItem(Item.SubItems.Add);
        Subitem.Text:='Subitem ' + Y.ToString;
      end;
    end;
    Collection1.Searlizetofile('.\file1.txt');
    Collection1.Free;
    Collection1:=TMyCollection.Create(TItem);
    JSONFileToObject('.\file1.txt', Collection1, nil);
    Writeln(Collection1.Serialize);
    Writeln(GetTickCount64.ToString);
    Readln;
  except
    on E: Exception do
    Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Last edited by turrican (2015-06-09 12:02:33)

Offline

#6 2015-06-09 13:12:12

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

Re: Stucked at deserialization

SubItems property type is unknown I guess...

Offline

#7 2015-06-09 20:54:04

turrican
Member
From: Barcelona
Registered: 2015-06-05
Posts: 94
Website

Re: Stucked at deserialization

Thanks ab,

I managed to do this with your help!

Thanks again!

Offline

#8 2017-09-30 02:45:38

eraldo
Member
From: Brasil
Registered: 2010-07-22
Posts: 69
Website

Re: Stucked at deserialization

Please,

Where is the error in the code?

Offline

Board footer

Powered by FluxBB