[英]Can I serialize an interface(_recordset) with TJSONMarshal?
I'm trying to serialize objects with TJSONMarshal (XE4) but I have a problem when objects has interfaces properties like _recordset 我正在尝试使用TJSONMarshal(XE4)序列化对象,但是当对象具有_recordset之类的接口属性时,我遇到了问题
eg 例如
My class: 我的课:
TFoo = class
private
FrsFoo: _recordset;
FFooProp: integer;
published
property rsFoo: _recordset read FrsFoo write FrsFoo;
property FooProp: integer read FFooProp write FFooProp;
end;
My function: 我的功能:
function TestSerialize: string;
var
JsonMarshal: TJSONMarshal;
Foo: TFoo;
begin
JsonMarshal := TJSONMarshal.Create(TJSONConverter.Create);
Foo := TFoo.Create;
Result := JsonMarshal.Marshal(Foo).ToString;
end;
It results: 结果:
{"type":"uTest.TFoo","id":1,"fields":{"FFooProp":0}}
{ “类型”: “uTest.TFoo”, “ID”:1, “字段”:{ “FFooProp”:0}}
rsFoo isn't serialized! rsFoo未序列化!
Can I serialize it? 我可以序列化吗? or its a limitation of TJSONMarshal?
还是TJSONMarshal的局限性?
In my case I just want to serialize _recordsets so my solution was: 就我而言,我只想序列化_recordsets,所以我的解决方案是:
1) Get all _Recordset type fields: 1)获取所有_Recordset类型的字段:
function Test.GetRecordsetFieldsFromObject(
AObject: TObject): TStringList;
var
Obj: TRttiType;
Rtti: TRTTIContext;
ObjField: TRttiField;
IntfObj: IInterface;
rsOut: _recordset;
begin
Result := TStringList.Create;
Obj := Rtti.GetType(AObject.ClassType);
for ObjField in Obj.GetFields do
if ObjField.FieldType.TypeKind = tkInterface then
begin
IntfObj := ObjField.GetValue(AObject).AsInterface;
if IntfObj.QueryInterface(_Recordset, rsOut) = 0 then
begin
Result.Add(ObjField.Name);
rsOut := nil;
end;
end;
end;
2) Register converter and reverter for each field founded 2)建立的每个字段的寄存器转换器和转换器
for FieldName in FieldNameList do
begin
JsonMarshal.RegisterConverter(TFoo, FieldName, function(Data: TObject; Field: String): TListOfStrings
var
Obj: TRttiType;
ObjField: TRttiField;
rsProp: _Recordset;
strStream: TStringStream;
begin
SetLength(Result, 1);
strStream := TStringStream.Create;
try
Obj := Rtti.GetType(data.ClassType);
ObjField := Obj.GetField(Field);
rsProp := ObjField.GetValue(Data).AsInterface as _Recordset;
rsProp.Save(TStreamAdapter.Create(strStream) as IUnknown, adPersistXML);
Result[0] := strStream.DataString;
finally
rsProp := nil;
strStream.Free;
end;
end);
JsonUnMarshal.RegisterReverter(TFoo, FieldName, procedure(Data: TObject; Field: String; Args: TListOfStrings)
var
Obj: TRttiType;
ObjField: TRttiField;
rsProp: _Recordset;
strStream: TStringStream;
begin
rsProp := coRecordset.Create;
strStream := TStringStream.Create(Args[0]);
try
Obj := Rtti.GetType(data.ClassType);
ObjField := Obj.GetField(Field);
strStream.Position := 0;
rsProp.Open(TStreamAdapter.Create(strStream) as IUnknown, EmptyParam, adOpenUnspecified, adLockUnspecified, 0);
ObjField.SetValue(Data, TValue.From<_Recordset>(rsProp));
finally
rsProp := nil;
strStream.Free;
end;
end);
end;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.