Deserialization JSON to objects with interface fields using SuperObject

I'm having trouble deserializing an object containing a interface field from json using SuperObject (serialization works fine) on DXE2. Consider the following: ITest = interface(IInterface) ['{9E5623FF-1BC9-4FFA-919D-80C45EE24F38}'] function GetField3() : string; procedure SetField3(Value: string); property FField3: string read GetField3 write SetField3; end; TTest = class(TInterfacedObject, ITest) private FField3: string; function GetField3() : string; procedure SetField3(Value: string); public property Field3: string read GetField3 write SetField3; constructor Create(Field3: string); end; TMyClass = class(TObject) public FField1: string; FField2: string; FTest: ITest; constructor Create(Field1: string; Field2: string; Test: ITest); end; // TTest-stuff omitted for brevity. constructor TMyClass.Create(Field1, Field2: string; Test: ITest); begin FField1 := Field1; FField2 := Field2; FTest := Test; end; var MyClass: TMyClass; MyClass2: TMyClass; JSONObj: ISuperObject; SuperContext: TSuperRttiContext; begin MyClass := TMyClass.Create('Test1', 'Test2', TTest.Create('Test3')); SuperContext := TSuperRttiContext.Create(); JSONObj := SuperContext.AsJson(MyClass); WriteLn(JSONObj.AsString); MyClass2 := SuperContext.AsType(JSONObj); MyClass2.Free(); ReadLn; end. When execution gets to `TSuperRttiContext.FromJson.FromClass` checking the `FTest`-field, the doo-doo hits the propeller in the ceiling (or table mounted, if you prefer that). At this point, `Result := FromJson(f.FieldType.Handle, GetFieldDefault(f, obj.AsObject[GetFieldName(f)]), v);` is called, which leads us into the interesting part of the SuperObject.pas code. I'll duplicated it here for brevity. procedure FromInterface; const soguid: TGuid = '{4B86A9E3-E094-4E5A-954A-69048B7B6327}'; var o: ISuperObject; begin if CompareMem(@(GetTypeData(TypeInfo).Guid), @soguid, SizeOf(TGUID)) then begin if obj <> nil then TValue.Make(@obj, TypeInfo, Value) else begin o := TSuperObject.Create(stNull); TValue.Make(@o, TypeInfo, Value); end; Result := True; end else Result := False; end; The value assigned to `soguid` is that of `ISuperObject`, so clearly the two won't match (I'm testing for `ITest`, remember?). And so I'm a little lost of what to make of this. Is it illegal to deserialize any object composed of one or more interface fields? This seems like such a common use case, that I find it hard to believe. I can appreciate the fact that knowing what implementation of a given interface to choose may be non-trivial. Yet, I see from the comment in the preamble, that interfaced objects are supposed to be supported - Sure would be great if anyone have solved this out there. Thanks! :)
Did you (also) ask on the superobject forum at

以上就是Deserialization JSON to objects with interface fields using SuperObject的详细内容,更多请关注web前端其它相关文章!

赞(0) 打赏
未经允许不得转载:web前端首页 » JSON 答疑

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

前端开发相关广告投放 更专业 更精准