【问题标题】:Automatically serializing a TObject to JSON using mormot使用 mormot 自动将 TObject 序列化为 JSON
【发布时间】:2018-02-17 23:49:32
【问题描述】:

我正在尝试使用 mORMot 框架将 TObject 序列化为 JSON。不幸的是,结果始终为空。

我要序列化的类是:

type ApmTime = class(TObject)
private
  function currentTime() : String;
published
  property Current_time: String read currentTime;
public
  constructor Create;
end;

constructor ApmTime.Create;
begin
  inherited;
end;

function ApmTime.currentTime() : String;
begin
  result :=  TimeToStr(Now);
end;

并且对应的mORMot方法在SynCommons中定义:

currentTime := ApmTime.Create;
Write(ObjectToJSON(currentTime, [woFullExpand]));

这总是返回空值。在单步执行TTextWriter.WriteObject(位于单元SynCommons)之后,以下代码似乎是将生成的json 设置为null:

if not(woFullExpand in Options) or
       not(Value.InheritsFrom(TList)
       {$ifndef LVCL} or Value.InheritsFrom(TCollection){$endif}) then
      Value := nil;
  if Value=nil then begin
    AddShort('null');
    exit;

我期待一些事情:

{
  "Current_time" : "15:04"
}

【问题讨论】:

    标签: delphi mormot


    【解决方案1】:

    昨天遇到了这个问题并弄清楚了发生了什么,所以为了未来的人们也会遇到这个问题:

    如果您只将 SynCommons.pas 添加到您的 uses 子句,则默认 DefaultTextWriterJSONClass 设置为 TTextWriter,它仅支持序列化特定的类类型,如您所见,不支持任意类/对象。请参阅 SynCommons.pas 中设置此默认值的以下行:

    var
      DefaultTextWriterJSONClass: TTextWriterClass = TTextWriter;
    

    现在,为了支持将任意对象序列化为 JSON,需要将此全局变量从默认的 TTextWriter 更改为 TJSONSerializer。

    这个类是在mORMot.pas中定义的,事实上,如果你将mORMot.pas添加到你的uses子句中,它的初始化会覆盖上面的默认值,并将TJSONSerializer设置为你的新默认值。

    如果您仔细阅读,此行为实际上记录在 SynCommons.pas 中,例如参见“SetDEfaultJSONClass()”类方法的 cmets:

    // you can use this method to override the default JSON serialization class
    // - if only SynCommons.pas is used, it will be TTextWriter
    // - but mORMot.pas initialization will call it to use the TJSONSerializer
    // instead, which is able to serialize any class as JSON
    class procedure SetDefaultJSONClass(aClass: TTextWriterClass);
    

    简而言之:要解决您的问题,只需将 mORMot.pas 添加到您的 uses 子句中,以及您应该已经拥有的 SynCommons.pas 中。

    【讨论】:

      【解决方案2】:

      尝试向已发布的属性添加写入。

      property Current_time: String read currentTime write SetCurrentTime. 
      

      只读属性未序列化。 ApmTime 也应该基于 TPersistent

      type 
        ApmTime = class(TPersistent)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-19
        • 2019-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-30
        相关资源
        最近更新 更多