Delphi :使用TJson.JsonToObject反序列化TList< T>

ie3xauqp  于 2023-04-20  发布在  其他
关注(0)|答案(2)|浏览(332)

考虑这个测试类:

TUser = class
  Name: string;
  constructor Create(AName: string);
end;

TTestClass = class
  Users:  TList<TUser>;
  constructor Create;
end;

序列化到JSON可以正常工作,但是当我尝试反序列化它时,列表没有填充:

procedure TForm21.Button1Click(Sender: TObject);
var
  u: TUser;
begin
  TestClass := TTestClass.Create;
  TestClass.Users.Add( TUser.Create('Nick'));
  TestClass.Users.Add( TUser.Create('Mike'));

  Memo1.Text := TJson.ObjectToJsonString(TestClass);
  TestClass2 := TJson.JsonToObject<TTestClass>( Memo1.Text );

  for u in TestClass2.Users do
    Memo1.Lines.Add(Format('User %s ', [ u.Name ]));
end;

JSON输出为:

{"users":{"listHelper":[2],"items":[["Nick"],["Mike"]]}}
bjp0bcyl

bjp0bcyl1#

字段名通常以“f”为前缀。当您将“users”重命名为“fUsers”时,您的代码将正常工作。
原因很简单,当你知道它的时候。f在json中看起来不太好。我猜这就是为什么他们在生成json时删除它,并在解析json时添加它的原因。
参见单元REST。JsonReflect方法:TJSONUnMarshal.ConvertFieldNameFromJson和TJSONConverter.ConvertFieldNameToJson

zdwk9cvp

zdwk9cvp2#

只是为了扩展“@coding Bott”的答案。
如果你想独立于“F”前缀,你可以使用存在于单元REST.Json.TypesJSONNameAttribute,以指定类中字段的名称。
您的示例可以更改为:

TTestClass = class
  [JSONName('Users')]
  Users:  TList<TUser>;
  constructor Create;
end;

正如您在TJSONConverter.ConvertFieldNameToJson中看到的,该方法首先检查是否应用了JsonNameAttribute,如果没有,则应用常规规则。

相关问题