使用mormot

时间:2018-02-17 23:49:32

标签: delphi mormot

我正在尝试使用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]));

这总是返回null。在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"
}

2 个答案:

答案 0 :(得分:1)

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

property Current_time: String read currentTime write SetCurrentTime. 

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

type 
  ApmTime = class(TPersistent)

答案 1 :(得分:1)

昨天碰到了这个问题,并弄清楚了发生了什么,因此也为将来的人们在这个问题上绊倒而造福:

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

var
  DefaultTextWriterJSONClass: TTextWriterClass = TTextWriter;

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

此类是在mORMot.pas中定义的,实际上,如果将mORMot.pas添加到uses子句中,则其初始化将覆盖上述默认值,并将TJSONSerializer设置为您的新默认值。

如果您仔细阅读以下内容,此行为实际上就会记录在SynCommons.pas中:请参见“ SetDEfaultJSONClass()”类方法的注释:

// 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添加到您应有的SynCommons.pas之外的use子句中。