Hello, I'm trying to test serialization:
type
TRecTest = class
private
FS1: string;
FI1: Integer;
public
property S1: string read FS1 write FS1;
property I1: Integer read fI1 write fI1;
function ToJSON: string;
end;
function TRecTest.ToJSON: string;
var
Serializer: TDataSnapJsonSerializer;
jValue: TJsonValue;
begin
Serializer := TDataSnapJsonSerializer.Create;
try
jValue := Serializer.ToJson(Self);
Result := jValue.ToJSON;
finally
Serializer.Free;
end;
end;
// testing
var
R: TRecTest;
sJSON: string;
...
R := TRecTest.Create;
R.S1 := 'Test Str';
R.I1 := 123;
sJSON := R.ToJSON;
// here is sJSON = {"$type":"fTest.TRecTest","$id":1}
Why sJSON is not contained values of fields?
Since you own Aurelius I would use the JSON serializer supplied with it.
It is located in \TMS Busines Core Library\source\core
with units Bcl.Json.Deserializer, Bcl.Json.Serializer, Bcl.Json.Attributes,
Your class would look like this using it.
[JsonNamingStrategy(TDefaultNamingStrategy)]
TRecTest = class
private
FS1: string;
FI1: Integer;
public
[JSONProperty]
property S1: string read FS1 write FS1;
[JSONProperty]
property I1: Integer read fI1 write fI1;
function ToJSON: string;
end;
function TRecTest.ToJson: String;
var JS : TJsonSerializer;
var V : TValue;
TT : TTypeToken;
SS : TStringStream;
begin
V := TValue.From(Self);
TT := TTypeToken.Create( V.TypeInfo);
try
SS := TStringStream.Create;
JS := TJsonSerializer.Create;
JS.Write(V,TT, SS);
Result := SS.DataString;
finally
JS.Free;
SS.Free;
end;
Thank you, your code works! And also my code works too with small additions for class:
[Entity]
TRecTest = class
private
FS1: string;
FI1: Integer;
public
[Column('S1', [TColumnProp.Required])]
property S1: string read FS1 write FS1;
[Column('I1', [TColumnProp.Required])]
property I1: Integer read fI1 write fI1;
function ToJSON: string; ;
end;
Mark , your code can be shortened to:
function TRecTest.ToJSON: string;
var
JS: TJsonSerializer;
begin
JS := TJsonSerializer.Create;
try
Result := JS.WriteAs<TRecTest>(Self);
finally
JS.Free;
end;
end;
It could, but I have a base class that I can derive from which has implemented in the base
LoadFrom
SaveTo
Strings, Streams, Files
and my method allows for that.
I also use a Generic TObjectList to do the same kind of thing.
e.g.
procedure TBEObjectList<T>.LoadFromStream(const Stream: TStream; const ITS : TInstanceTypeSerialization = TInstanceTypeSerialization.IfNeeded);
var V : TValue;
JD : TJsonDeserializer;
TT : TTypeToken;
begin
Clear;
V := TValue.From(Self);
TT := TTypeToken.Create( V.TypeInfo);
JD := TJsonDeserializer.Create;
JD.Converters.ObjectConverterFactory.InstanceTypeSerialization := ITS;
try
Stream.Position := 0;
JD.Read(Stream, V, TT);
finally
JD.Free;
end;
end;
I have two base classes
TBaseEntity
and
TBEObjectList<T: TBaseEntity> = class(TObjectList<T>)
which I use to bind to the TMSAureliusDataset and my generic serialization works well for that.
e.g. my TBaseEntity LoadFromJson method.
procedure TBaseEntity.LoadFromJson(const Json: String);
var V : TValue;
JD : TJsonDeserializer;
TT : TTypeToken;
begin
V := TValue.From(Self);
TT := TTypeToken.Create( V.TypeInfo);
JD := TJsonDeserializer.Create;
try
JD.Read(Json,V, TT);
Loaded;
finally
JD.Free;
end;
end;
Thank you for the code!
Mark, can you provide an example for TBEObjectList<T> usage?
wlandgraf
(Wagner Landgraf)
November 19, 2019, 12:52am
8
Mark, your code can be shortened to:
function TRecTest.ToJSON: string;
var
JS: TJsonSerializer;
begin
JS := TJsonSerializer.Create;
try
Result := JS.WriteAs(Self);
finally
JS.Free;
end;
end;
It could be even more simplified this way:
function TRecTest.ToJSON: string;
begin
Result := TJson.SerializeAs<TRecTest>(Self);
end;
Wagner R. Landgraf2019-11-19 00:52:51