【问题标题】:Serializing JSON object for an instance instantiated through a metaclass为通过元类实例化的实例序列化 JSON 对象
【发布时间】:2013-08-08 13:35:02
【问题描述】:

SuperObject 库有一个用于序列化对象的通用方法:

type
   TSomeObject = class
   ...
   end;

var
   lJSON       : ISuperObject;
   lContext    : TSuperRttiContext;
   lSomeObject : TSomeObject;
begin
   lSomeObject := TSomeObject.Create;
   lContext := TSuperRttiContext.Create;
   lJSON := lContext.AsJson<TSomeObject>(lSomeObject);

但现在我正在处理元类实例。
这是对象结构:

TJSONStructure = class(TObject);

TReqBase = class(TJSONStructure)
private
   token: Int64;
public
end;

TReqLogin = class(TReqBase)
private
   username,
   password: String;
   module  : Integer;
public
end;


type
   TWebAct = (ttlogin,
              ttsignin);

TReqClass = class of TReqBase;

const
   cWebActStructures: Array[TWebAct] of
   record
      RequestClass : TReqClass;
   end
   = (
      { ttlogin  } (RequestClass: TReqLogin;),
      { ttsignin } (RequestClass: TReqSignIn;)     // Not in definitions above
     ); 

如果我现在尝试:

var
   lContext      : TSuperRttiContext;
   lJSON         : ISuperObject;
   lRequestClass : TReqClass;
   lRequestBase  : TReqBase;
begin
   lRequestClass := cWebActStructures[ttlogin].RequestClass;
   lRequestBase := lRequestClass.Create;     // instance of type TReqLogin
   lContext := TSuperRttiContext.Create;
   lJSON := lContext.AsJson<TReqBase>(lRequestBase);

我得到了 TReqBase 序列化:lJSON.AsString = '{"token":-12346789}'
我想让 TReqLogin 序列化。
试过了:

  • lContext.AsJson(lRequestBase);不起作用:不兼容的类型)[此外,我必须在我的例程中列出/处理所有可能的 RequestClass 类型]

  • lContext.AsJson(lRequestBase) 都没有:E2531 方法“AsJson”需要显式类型参数

有什么方法可以让我的 lRequestBase 序列化为 TReqLogin、TReq...,而无需为它们全部编码?

【问题讨论】:

  • 啊,混合元类、SuperObject 和泛型是我们 :-D。顺便说一句,您不是在处理元类实例。只是通过元类实例化的普通实例。您能否确认它确实是正在创建的 TReqLogin?如果是,那么您需要将正确的类型传递给 AsJson 方法。 IIRC 确实有一种方法可以从实例中获取它并将其作为类型传递给 AsJson 方法,但我需要在另一台机器上进行挖掘(这台机器上没有 Delphi)。顺便说一句,你正在做的事情很好。
  • 确实是一个正在创建的TReqLogin。从实例中获取它的一种方法是 lRequestBase.ClassType 但这不会输入到 AsJson (第二个要点)
  • 是的,我知道。刚刚启动了另一台机器,即将开始挖掘。这也是我想在工作中实施的事情,所以时间花得很好。
  • 您使用的是什么版本的 SuperObject?我必须定义 VER210 才能访问 TSuperRttiContext 并且现在超级对象无法在 XE2 中编译,因为它仍然使用 TValueData.FHeapData 而不是新的 FValueData(使用来自code.google.com/p/superobject/downloads/list的最新 1.2.4 版本@
  • 我已经对 1.2.4 进行了这些更改,只是将 FHeapData 替换为 FValueData。之后用于 JSON(反)序列化的 Testapp 运行良好。哦,禁用 NT_COMPATIBILIY 定义(IIRC)在这些例程中存在夏令时错误。谁再用 NT?

标签: delphi generics delphi-xe2 superobject


【解决方案1】:

诀窍是不创建一个TSuperRttiContext 并自己调用它的 AsJSOn 方法,而是立即使用:

lJSON := RequestBase.ToJSON;

ToJSON 方法随后将在后台创建一个 TSuperRttiContext 并处理必要的转换。

非常感谢Marjan 的帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 2021-07-22
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多