You are not logged in.
Pages: 1
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! ![]()
Offline
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.
Online
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.
Online
Hi ab,
- 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
Pages: 1