mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-15 07:45:54 +01:00
JSON properties can be de/serialized verbatim by the default json serializer
This commit is contained in:
parent
bedc034e6d
commit
23a108896c
@ -135,6 +135,7 @@ Render(lPerson, False,
|
||||
- New! `TMVCActiveRecord.DeleteRQL` deletes records using an `RQL` expression as `where` clause.
|
||||
- New! Microsoft SQLServer Support in `MVCActiveRecord` and RQL (*thanks to one of the biggest Delphi based company in Italy which heavily uses DMVCFramework* and *[DMSContainer](http://www.bittimeprofessionals.it/prodotti/dmscontainer)*)
|
||||
- New! SQLite support in `MVCActiveRecord` and RQL, so that `MVCActiveRecord` can be used also for Delphi mobile projects!
|
||||
- Default JSON Serializer can verbatim pass properties with type `JsonDataObjects.TJSONObject` without using `string` as carrier of JSON
|
||||
- Improved! `ActiveRecordShowCase` sample is much better now.
|
||||
- Improved! In case of unhandled exception `TMVCEngine` is compliant with the default response content-type (usually it did would reply using `text/plain`).
|
||||
- **Breaking Change!** In `MVCActiveRecord` attribute `MVCPrimaryKey` has been removed and merged with `MVCTableField`, so now `TMVCActiveRecordFieldOption` is a set of `foPrimaryKey`, `foAutoGenerated`, `foTransient` (check `activerecord_showcase.dproj` sample).
|
||||
|
@ -28,7 +28,7 @@ interface
|
||||
|
||||
uses
|
||||
MVCFramework.Serializer.Commons,
|
||||
Generics.Collections, Vcl.Graphics;
|
||||
Generics.Collections, Vcl.Graphics, JsonDataObjects;
|
||||
|
||||
type
|
||||
|
||||
@ -72,6 +72,19 @@ type
|
||||
property DOB: TDate read GetDOB write SetDOB;
|
||||
end;
|
||||
|
||||
TObjectWithJSONObject = class
|
||||
private
|
||||
fJSONObject: TJSONObject;
|
||||
FStringProp: String;
|
||||
procedure SetStringProp(const Value: String);
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
property StringProp: String read FStringProp write SetStringProp;
|
||||
property JSONObject: TJSONObject read fJSONObject;
|
||||
end;
|
||||
|
||||
|
||||
[MVCNameCase(ncCamelCase)]
|
||||
TInterfacedPerson = class(TInterfacedObject, IPerson)
|
||||
private
|
||||
@ -416,6 +429,25 @@ begin
|
||||
fName := Value;
|
||||
end;
|
||||
|
||||
{ TObjectWithJSONObject }
|
||||
|
||||
constructor TObjectWithJSONObject.Create;
|
||||
begin
|
||||
inherited;
|
||||
fJSONObject := TJsonObject.Create;
|
||||
end;
|
||||
|
||||
destructor TObjectWithJSONObject.Destroy;
|
||||
begin
|
||||
fJSONObject.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
procedure TObjectWithJSONObject.SetStringProp(const Value: String);
|
||||
begin
|
||||
FStringProp := Value;
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
Randomize;
|
||||
|
@ -22,10 +22,8 @@ object MainForm: TMainForm
|
||||
ActivePage = TabSheet1
|
||||
Align = alClient
|
||||
TabOrder = 0
|
||||
ExplicitWidth = 846
|
||||
object TabSheet1: TTabSheet
|
||||
Caption = 'Invoking Plain PODO'
|
||||
ExplicitWidth = 838
|
||||
object GroupBox1: TGroupBox
|
||||
Left = 3
|
||||
Top = 22
|
||||
@ -182,18 +180,18 @@ object MainForm: TMainForm
|
||||
TabOrder = 13
|
||||
end
|
||||
object btnDates: TButton
|
||||
Left = 635
|
||||
Left = 716
|
||||
Top = 30
|
||||
Width = 165
|
||||
Width = 84
|
||||
Height = 25
|
||||
Caption = 'PlayWithDates'
|
||||
TabOrder = 14
|
||||
OnClick = btnDatesClick
|
||||
end
|
||||
object btnFloatsTests: TButton
|
||||
Left = 545
|
||||
Left = 626
|
||||
Top = 30
|
||||
Width = 75
|
||||
Width = 84
|
||||
Height = 25
|
||||
Caption = 'Floats'
|
||||
TabOrder = 15
|
||||
@ -337,7 +335,6 @@ object MainForm: TMainForm
|
||||
object TabSheet2: TTabSheet
|
||||
Caption = 'Invoking DataModule Methods'
|
||||
ImageIndex = 1
|
||||
ExplicitWidth = 838
|
||||
object GroupBox5: TGroupBox
|
||||
Left = 11
|
||||
Top = 18
|
||||
@ -378,6 +375,15 @@ object MainForm: TMainForm
|
||||
end
|
||||
end
|
||||
end
|
||||
object btnWithJSON: TButton
|
||||
Left = 552
|
||||
Top = 76
|
||||
Width = 75
|
||||
Height = 25
|
||||
Caption = 'JSON Prop'
|
||||
TabOrder = 1
|
||||
OnClick = btnWithJSONClick
|
||||
end
|
||||
object DataSource1: TDataSource
|
||||
DataSet = FDMemTable1
|
||||
Left = 767
|
||||
|
@ -76,6 +76,7 @@ type
|
||||
CheckBox1: TCheckBox;
|
||||
btnDates: TButton;
|
||||
btnFloatsTests: TButton;
|
||||
btnWithJSON: TButton;
|
||||
procedure btnSubstractClick(Sender: TObject);
|
||||
procedure btnReverseStringClick(Sender: TObject);
|
||||
procedure edtGetCustomersClick(Sender: TObject);
|
||||
@ -90,6 +91,7 @@ type
|
||||
procedure btnSearchClick(Sender: TObject);
|
||||
procedure btnDatesClick(Sender: TObject);
|
||||
procedure btnFloatsTestsClick(Sender: TObject);
|
||||
procedure btnWithJSONClick(Sender: TObject);
|
||||
private
|
||||
FExecutor: IMVCJSONRPCExecutor;
|
||||
FExecutor2: IMVCJSONRPCExecutor;
|
||||
@ -307,6 +309,25 @@ begin
|
||||
edtResult.Text := lResp.Result.AsInteger.ToString;
|
||||
end;
|
||||
|
||||
procedure TMainForm.btnWithJSONClick(Sender: TObject);
|
||||
var
|
||||
lPerson: TJsonObject;
|
||||
lReq: IJSONRPCRequest;
|
||||
lResp: IJSONRPCResponse;
|
||||
begin
|
||||
lReq := TJSONRPCRequest.Create;
|
||||
lReq.Method := 'SaveObjectWithJSON';
|
||||
lReq.RequestID := 1234;
|
||||
lPerson := TJsonObject.Create;
|
||||
lReq.Params.Add(lPerson, pdTJDOJsonObject);
|
||||
lPerson.S['StringProp'] := 'Hello World';
|
||||
lPerson.O['JSONObject'] := TJsonObject.Parse('{"name":"Daniele"}') as TJsonObject;
|
||||
lResp := FExecutor.ExecuteRequest(lReq);
|
||||
|
||||
lPerson := lResp.Result.AsObject as TJsonObject;
|
||||
ShowMessage(lPerson.ToJSON(False));
|
||||
end;
|
||||
|
||||
procedure TMainForm.edtGetCustomersClick(Sender: TObject);
|
||||
var
|
||||
lReq: IJSONRPCRequest;
|
||||
|
@ -64,19 +64,44 @@ type
|
||||
function SavePerson(const aPerson: TJsonObject): Integer;
|
||||
function FloatsTest(const aDouble: Double; const aExtended: Extended): Extended;
|
||||
procedure DoSomething;
|
||||
function SaveObjectWithJSON(const WithJSON: TJsonObject): TJsonObject;
|
||||
// invalid parameters modifiers
|
||||
procedure InvalidMethod1(var MyVarParam: Integer);
|
||||
procedure InvalidMethod2(out MyOutParam: Integer);
|
||||
|
||||
end;
|
||||
|
||||
TUtils = class sealed
|
||||
class function JSONObjectAs<T: constructor, class>(const JSON: TJsonObject): T;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
MVCFramework.Logger,
|
||||
System.StrUtils,
|
||||
System.DateUtils;
|
||||
System.DateUtils, MVCFramework.Serializer.JsonDataObjects;
|
||||
|
||||
class function TUtils.JSONObjectAs<T>(const JSON: TJsonObject): T;
|
||||
var
|
||||
lObj: TObject;
|
||||
lSerializer: TMVCJsonDataObjectsSerializer;
|
||||
begin
|
||||
lObj := T.Create;
|
||||
try
|
||||
lSerializer := TMVCJsonDataObjectsSerializer.Create;
|
||||
try
|
||||
lSerializer.JsonObjectToObject(JSON, lObj, TMVCSerializationType.stProperties, []);
|
||||
finally
|
||||
lSerializer.Free;
|
||||
end;
|
||||
except
|
||||
lObj.Free;
|
||||
raise;
|
||||
end;
|
||||
Result := T(lObj);
|
||||
end;
|
||||
|
||||
{ TMyDerivedController }
|
||||
|
||||
@ -85,8 +110,7 @@ begin
|
||||
|
||||
end;
|
||||
|
||||
function TMyObject.FloatsTest(const aDouble: Double;
|
||||
const aExtended: Extended): Extended;
|
||||
function TMyObject.FloatsTest(const aDouble: Double; const aExtended: Extended): Extended;
|
||||
begin
|
||||
Result := aDouble + aExtended;
|
||||
end;
|
||||
@ -224,6 +248,19 @@ begin
|
||||
Result := Result.ToUpper;
|
||||
end;
|
||||
|
||||
function TMyObject.SaveObjectWithJSON(const WithJSON: TJsonObject): TJsonObject;
|
||||
var
|
||||
lObj: TObjectWithJSONObject;
|
||||
begin
|
||||
lObj := TUtils.JSONObjectAs<TObjectWithJSONObject>(WithJSON);
|
||||
try
|
||||
LogD(lObj);
|
||||
Result := WithJSON.Clone as TJsonObject;
|
||||
finally
|
||||
lObj.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMyObject.SavePerson(const aPerson: TJsonObject): Integer;
|
||||
// var
|
||||
// lPerson: TPerson;
|
||||
|
@ -167,6 +167,11 @@ type
|
||||
[MVCPath('/simplearray')]
|
||||
procedure GetSimpleArrays;
|
||||
|
||||
[MVCHTTPMethod([httpGET])]
|
||||
[MVCPath('/objectwithjson')]
|
||||
procedure GetObjectWithJSONProperty;
|
||||
|
||||
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -524,6 +529,17 @@ begin
|
||||
Render<TPerson>(GetPeopleList, False);
|
||||
end;
|
||||
|
||||
procedure TRenderSampleController.GetObjectWithJSONProperty;
|
||||
var
|
||||
lObj: TObjectWithJSONObject;
|
||||
begin
|
||||
lObj := TObjectWithJSONObject.Create;
|
||||
lObj.StringProp := 'Daniele Teti';
|
||||
lObj.JSONObject.S['stringprop'] := 'String Prop';
|
||||
lObj.JSONObject.O['innerobj'].S['innerstringprop'] := 'Inner String Prop';
|
||||
Render(lObj);
|
||||
end;
|
||||
|
||||
procedure TRenderSampleController.GetPerson_AsHTML;
|
||||
begin
|
||||
ResponseStream.Append('<html><body><ul>').Append('<li>FirstName: Daniele</li>').Append('<li>LastName: Teti')
|
||||
|
@ -36,17 +36,17 @@ uses
|
||||
Web.WebReq,
|
||||
Web.WebBroker,
|
||||
MVCFramework.Console,
|
||||
WebModuleU in 'WebModuleU.pas' {WebModule1: TWebModule} ,
|
||||
WebModuleU in 'WebModuleU.pas' {WebModule1: TWebModule},
|
||||
RenderSampleControllerU in 'RenderSampleControllerU.pas',
|
||||
BusinessObjectsU in '..\commons\BusinessObjectsU.pas',
|
||||
MyDataModuleU in 'MyDataModuleU.pas' {MyDataModule: TDataModule} ,
|
||||
MyDataModuleU in 'MyDataModuleU.pas' {MyDataModule: TDataModule},
|
||||
CustomTypesU in 'CustomTypesU.pas',
|
||||
CustomTypesSerializersU in 'CustomTypesSerializersU.pas',
|
||||
InMemoryDataU in 'InMemoryDataU.pas',
|
||||
MVCFramework.DataSet.Utils in '..\..\sources\MVCFramework.DataSet.Utils.pas',
|
||||
RandomUtilsU in '..\commons\RandomUtilsU.pas',
|
||||
MVCFramework.Serializer.JsonDataObjects.OptionalCustomTypes
|
||||
in '..\..\sources\MVCFramework.Serializer.JsonDataObjects.OptionalCustomTypes.pas';
|
||||
MVCFramework.Serializer.JsonDataObjects.OptionalCustomTypes in '..\..\sources\MVCFramework.Serializer.JsonDataObjects.OptionalCustomTypes.pas',
|
||||
MVCFramework.Serializer.JsonDataObjects.CustomTypes in '..\..\sources\MVCFramework.Serializer.JsonDataObjects.CustomTypes.pas';
|
||||
|
||||
{$R *.res}
|
||||
|
||||
|
@ -148,6 +148,7 @@
|
||||
<DCCReference Include="..\..\sources\MVCFramework.DataSet.Utils.pas"/>
|
||||
<DCCReference Include="..\commons\RandomUtilsU.pas"/>
|
||||
<DCCReference Include="..\..\sources\MVCFramework.Serializer.JsonDataObjects.OptionalCustomTypes.pas"/>
|
||||
<DCCReference Include="..\..\sources\MVCFramework.Serializer.JsonDataObjects.CustomTypes.pas"/>
|
||||
<None Include="ModelSupport_renders\default.txaPackage"/>
|
||||
<None Include="ModelSupport_renders\default.txvpck"/>
|
||||
<None Include="ModelSupport_renders\WebModuleU\default.txaPackage"/>
|
||||
@ -322,6 +323,12 @@
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\RenderSampleControllerU\default.txaPackage" Configuration="Release" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txvpck" Configuration="Release" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
@ -333,37 +340,31 @@
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txvpck" Configuration="Debug" Class="ProjectFile">
|
||||
<Platform Name="Linux64">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\default.txvpck" Configuration="Release" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\renders1\default.txvpck" Configuration="Release" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txaPackage" Configuration="Debug" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="bin\renders.exe" Configuration="Release" Class="ProjectOutput">
|
||||
<Platform Name="Win32">
|
||||
<RemoteName>renders.exe</RemoteName>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txvpck" Configuration="Debug" Class="ProjectFile">
|
||||
<Platform Name="Linux64">
|
||||
<DeployFile LocalName="ModelSupport_renders\renders1\default.txvpck" Configuration="Release" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="ModelSupport_renders\RenderSampleControllerU\default.txaPackage" Configuration="Release" Class="ProjectFile">
|
||||
<DeployFile LocalName="ModelSupport_renders\renders\default.txaPackage" Configuration="Debug" Class="ProjectFile">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>.\</RemoteDir>
|
||||
<Overwrite>true</Overwrite>
|
||||
|
@ -54,8 +54,8 @@ begin
|
||||
// Max request size in bytes
|
||||
Config[TMVCConfigKey.MaxRequestSize] := IntToStr(TMVCConstants.DEFAULT_MAX_REQUEST_SIZE);
|
||||
end);
|
||||
FMVC.AddController(TMyController);
|
||||
// To enable compression (deflate, gzip) just add this middleware as the last one
|
||||
// FMVC.AddController(TMyController);
|
||||
// To enable compression (deflate, gzip) just add this middleware as the last one
|
||||
FMVC.AddMiddleware(TMVCCompressionMiddleware.Create);
|
||||
end;
|
||||
|
||||
|
@ -3,6 +3,10 @@ program swaggeruiwebserver;
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
uses
|
||||
{$IFDEF MSWINDOWS}
|
||||
WinAPI.ShellAPI,
|
||||
WinAPI.Windows,
|
||||
{$ENDIF}
|
||||
System.SysUtils,
|
||||
MVCFramework.Logger,
|
||||
MVCFramework.Commons,
|
||||
|
@ -43,8 +43,6 @@ type
|
||||
|
||||
TMVCStreamSerializerJsonDataObject = class(TInterfacedObject, IMVCTypeSerializer)
|
||||
protected
|
||||
// procedure Serialize(const AElementValue: TValue; var ASerializerObject: TObject;
|
||||
// const AAttributes: TArray<TCustomAttribute>);
|
||||
procedure SerializeAttribute(const AElementValue: TValue; const APropertyName: string;
|
||||
const ASerializerObject: TObject; const AAttributes: TArray<TCustomAttribute>);
|
||||
procedure SerializeRoot(const AObject: TObject; out ASerializerObject: TObject;
|
||||
|
@ -186,7 +186,6 @@ begin
|
||||
fStringDictionarySerializer := TMVCStringDictionarySerializer.Create;
|
||||
GetTypeSerializers.Add(TypeInfo(TMVCStringDictionary), TMVCStringDictionarySerializer.Create);
|
||||
GetTypeSerializers.Add(TypeInfo(TGUID), TMVCGUIDSerializer.Create);
|
||||
|
||||
end;
|
||||
|
||||
procedure TMVCJsonDataObjectsSerializer.AttributeToJsonDataValue(const AJsonObject: TJDOJsonObject; const AName: string;
|
||||
@ -315,6 +314,10 @@ begin
|
||||
ChildJsonArray := AJsonObject.A[AName];
|
||||
DataSetToJsonArray(TDataSet(ChildObject), ChildJsonArray, TMVCNameCase.ncLowerCase, []);
|
||||
end
|
||||
else if ChildObject is TJsonObject then
|
||||
begin
|
||||
AJsonObject.O[AName] := TJsonObject(ChildObject).Clone as TJsonObject;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ChildList := TDuckTypedList.Wrap(ChildObject);
|
||||
@ -1092,6 +1095,16 @@ var
|
||||
AttributeValue: TValue;
|
||||
lKeyName: string;
|
||||
begin
|
||||
if AObject is TJsonObject then
|
||||
begin
|
||||
if not Assigned(AObject) then
|
||||
begin
|
||||
raise EMVCDeserializationException.Create(AObject.ClassName + ' is not assigned');
|
||||
end;
|
||||
TJsonObject(AObject).Assign(AJsonObject);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
ObjType := GetRttiContext.GetType(AObject.ClassType);
|
||||
case AType of
|
||||
stDefault, stProperties:
|
||||
|
@ -28,7 +28,7 @@ interface
|
||||
|
||||
uses
|
||||
system.TimeSpan, system.SysUtils, generics.collections, system.Classes,
|
||||
system.Rtti, MVCFramework.Serializer.Commons;
|
||||
system.Rtti, MVCFramework.Serializer.Commons, JsonDataObjects;
|
||||
|
||||
type
|
||||
TMyObject = class
|
||||
@ -47,6 +47,7 @@ type
|
||||
FPropTimeStamp: TTimeStamp;
|
||||
FPropTime: TTime;
|
||||
FPropCurrency: Currency;
|
||||
fPropJSONObject: TJSONObject;
|
||||
procedure SetPropAnsiString(const Value: AnsiString);
|
||||
procedure SetPropString(const Value: string);
|
||||
procedure SetPropInt64(const Value: Int64);
|
||||
@ -62,6 +63,8 @@ type
|
||||
procedure SetPropTime(const Value: TTime);
|
||||
procedure SetPropCurrency(const Value: Currency);
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function Equals(Obj: TMyObject): boolean; reintroduce;
|
||||
property PropString: string read FPropString write SetPropString;
|
||||
property PropAnsiString: AnsiString read FPropAnsiString
|
||||
@ -79,6 +82,7 @@ type
|
||||
property PropTimeStamp: TTimeStamp read FPropTimeStamp
|
||||
write SetPropTimeStamp;
|
||||
property PropCurrency: Currency read FPropCurrency write SetPropCurrency;
|
||||
property PropJSONObject: TJSONObject read fPropJSONObject;
|
||||
end;
|
||||
|
||||
TMyChildObject = class
|
||||
@ -345,6 +349,25 @@ begin
|
||||
Result.PropTime := EncodeTime(10, 20, 30, 40);
|
||||
Result.PropDateTime := Result.PropDate + Result.PropTime;
|
||||
Result.PropTimeStamp := DateTimeToTimeStamp(Result.PropDateTime + 1);
|
||||
Result.PropJSONObject.S['stringprop1'] := 'This is a string prop';
|
||||
Result.PropJSONObject.I['intprop1'] := 1234;
|
||||
Result.PropJSONObject.A['arrprop'].Add(1234);
|
||||
Result.PropJSONObject.A['arrprop'].Add('Hello World');
|
||||
Result.PropJSONObject.O['objprop'].S['innerprop1'] := 'value1';
|
||||
Result.PropJSONObject.O['objprop'].S['innerprop2'] := 'value2';
|
||||
Result.PropJSONObject.O['objprop'].S['innerprop3'] := 'value3';
|
||||
end;
|
||||
|
||||
constructor TMyObject.Create;
|
||||
begin
|
||||
inherited;
|
||||
fPropJSONObject := TJsonObject.Create;
|
||||
end;
|
||||
|
||||
destructor TMyObject.Destroy;
|
||||
begin
|
||||
fPropJSONObject.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TMyObject.Equals(Obj: TMyObject): boolean;
|
||||
@ -366,6 +389,7 @@ begin
|
||||
Obj.PropDateTime) = 0);
|
||||
Result := Result and (Self.PropTimeStamp.Date = Obj.PropTimeStamp.Date) and
|
||||
(Self.PropTimeStamp.Time = Obj.PropTimeStamp.Time);
|
||||
Result := Result and (Self.fPropJSONObject.ToJSON() = Obj.PropJSONObject.ToJSON());
|
||||
end;
|
||||
|
||||
procedure TMyObject.SetPropAnsiString(const Value: AnsiString);
|
||||
|
@ -58,6 +58,10 @@ type
|
||||
|
||||
{ serialize declarations }
|
||||
[Test]
|
||||
procedure TestSerializeAllTypes;
|
||||
[Test]
|
||||
procedure TestSerializeAllTypesInList;
|
||||
[Test]
|
||||
procedure TestSerializeEntity;
|
||||
[Test]
|
||||
procedure TestSerializeNil;
|
||||
@ -160,7 +164,7 @@ implementation
|
||||
|
||||
uses
|
||||
MVCFramework.Serializer.JsonDataObjects.CustomTypes,
|
||||
MVCFramework.Commons, System.TypInfo;
|
||||
MVCFramework.Commons, System.TypInfo, BOs;
|
||||
|
||||
const
|
||||
LINE_BREAK = #$A;
|
||||
@ -661,6 +665,59 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMVCTestSerializerJsonDataObjects.TestSerializeAllTypes;
|
||||
var
|
||||
lObj1, lObj2: TMyObject;
|
||||
lSer: string;
|
||||
begin
|
||||
lObj1 := GetMyObject;
|
||||
try
|
||||
lSer := FSerializer.SerializeObject(lObj1);
|
||||
lObj2 := TMyObject.Create;
|
||||
try
|
||||
FSerializer.DeserializeObject(lSer, lObj2);
|
||||
Assert.IsTrue(lObj1.Equals(lObj2));
|
||||
finally
|
||||
lObj2.Free;
|
||||
end;
|
||||
finally
|
||||
lObj1.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMVCTestSerializerJsonDataObjects.TestSerializeAllTypesInList;
|
||||
var
|
||||
lList1, lList2: TObjectList<TMyObject>;
|
||||
lSer: string;
|
||||
I: Integer;
|
||||
lObj: TMyObject;
|
||||
begin
|
||||
lList1 := TObjectList<TMyObject>.Create;
|
||||
try
|
||||
for I := 0 to 9 do
|
||||
begin
|
||||
lObj :=GetMyObject;
|
||||
lObj.PropJSONObject.I['value'] := I;
|
||||
lList1.Add(lObj);
|
||||
end;
|
||||
|
||||
lSer := FSerializer.SerializeCollection(lList1);
|
||||
|
||||
lList2 := TObjectList<TMyObject>.Create;
|
||||
try
|
||||
FSerializer.DeserializeCollection(lSer, lList2, TMyObject);
|
||||
for I := 0 to 9 do
|
||||
begin
|
||||
Assert.IsTrue(lList1[I].Equals(lList2[I]));
|
||||
end;
|
||||
finally
|
||||
lList2.Free;
|
||||
end;
|
||||
finally
|
||||
lList1.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMVCTestSerializerJsonDataObjects.TestSerializeCollection;
|
||||
const
|
||||
JSON =
|
||||
|
Loading…
Reference in New Issue
Block a user