TOL = class(TObject) public procedure W(W: TJsonWriter; Instance: TObject; Options: TTextWriterWriteObjectOptions); end; TPerson = class private FName: string; FID: integer; FSex: Byte; published property ID: integer read FID write FID; property name: string read FName write FName; property sex: Byte read FSex write FSex; end; TTestObject = class private FL: TObjectList<TPerson>; public constructor Create; published property L: TObjectList<TPerson> read FL write FL; end; procedure TForm1.Button3Click(Sender: TObject); begin var OL := TOL.Create; var TestObj := TTestObject.Create; for var I := 0 to 2 do begin var p := TPerson.Create; p.FName := 'JJW'; p.FID := 1; p.FSex := 1; TestObj.L.Add(p); end; //方法一 Rtti.RegisterClass(TObjectList<TPerson>).JsonSave := Rtti.RegisterClass(TObjectList).JsonSave; Memo1.Text := ObjectToJson(TestObj, [woObjectListWontStoreClassName]); //方法二 var rj := TRttiJson.RegisterCustomSerializerClass(TObjectList<TPerson>, nil, OL.W); var jsonStr: RawUtf8; SaveJson(TestObj, TypeInfo(TTestObject), [], jsonStr, [woObjectListWontStoreClassName]); Memo1.Text := jsonStr; end; { TOL } procedure TOL.W(W: TJsonWriter; Instance: TObject; Options: TTextWriterWriteObjectOptions); begin W.Add('['); var p := TList(Instance); for var I := 0 to P.Count-1 do W.WriteObject(P[I]); w.Add(']'); end;
针对 每个实体类,必须 TObjectList<TXXXObject> 注册一遍,感觉也挺麻烦的。
补充:
mormot.core.text 单元中 定义了一个全局的类 DefaultJsonWriter: TBaseWriterClass = TTextWriter;
但是mormot框架中,ObjectToJson或SaveJson中有的地方使用了这个全局writer,有些地方直接使用了TJsonWriter.Create.
{ TJsonWriterEx } procedure TJsonWriterEx.WriteObject(Value: TObject; WriteOptions: TTextWriterWriteObjectOptions); begin if Value.ToString.StartsWith('TObjectList<') then begin Self.Add('['); var L := TList(Value); for var I := 0 to L.Count-1 do begin var P := L[I]; Self.AddString(SaveJson(P, TObject(P).ClassInfo)); end; Self.Add(']'); end else begin if Self.fInternalJsonWriter<>nil then Form1.Memo1.Lines.Add('????'); // TTestObject = class // private // FL: TObjectList<TPerson>; // public // constructor Create; // destructor Destroy; override; // published // property L: TObjectList<TPerson> read FL write FL; // end; // Rtti.RegisterClass(Value.ClassType).JsonSave := Rtti.RegisterClass(TObjectList).JsonSave; var ri: TRttiCustom := Rtti.RegisterClass(PClass(Value)^); var c := ri.Props.Count; if c > 0 then begin for var I := 0 to C-1 do begin var p := ri.Props.List[I]; rtti.RegisterType(p.Value.Info); p.Value.JsonSave := Rtti.RegisterClass(TObjectList).JsonSave; end; end; inherited; end;
上面的代码并不完善,像TTestObject这样的嵌套类就不行了,需要递归处理,这很不值得,不如直接改写SaveJson或ObjectToJson源代码了。