Автоматическая сериализация TObject в JSON с помощью mormot
Я пытаюсь сериализовать объект TO в JSON с помощью фреймворка mORMot. К сожалению, результат всегда нулевой.
Класс, который я пытаюсь сериализовать:
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 установлен в нуль:
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"
}
1 ответ
Вчера заглянул в это и выяснил, что происходит, поэтому для будущих людей, наткнувшихся на эту проблему, также:
Если вы добавляете только SynCommons.pas в свое предложение using, тогда 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 в раздел using в дополнение к SynCommons.pas, который у вас уже должен быть.
Попробуйте добавить запись в опубликованную собственность.
property Current_time: String read currentTime write SetCurrentTime.
Свойство только для чтения не сериализуется. Также ApmTime должен быть основан на TPersistent
type
ApmTime = class(TPersistent)