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.
Offline
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
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