// How to hide “ownsObjects” and “listHelper” TObjectList's properties from a Json
type
TSameClass = class(...)
....
public
...
function GetAsJson: string;
...
end;
...
// метод любого класса Txxxxx для получения его json, у которого, для всех его
// переменных с типом TObjectList, будут очищены “ownsObjects” и “listHelper” свойства
function TSameClass.GetAsJson: string;
procedure ClearJsonObjectList(AJson: TJSONObject);
var je: TJSONObject.TEnumerator;
begin
// проходим по всему дереву json и удаляем ненужные нам пары
je := AJson.GetEnumerator();
while je.MoveNext() do
if je.Current.JsonValue is TJSONObject then
// рекурсивный вызов
ClearJsonObjectList(je.Current.JsonValue as TJSONObject)
else
// если есть этот Pair, то есть и другой
if Assigned(AJson.RemovePair('listHelper')) then
AJson.RemovePair('ownsObjects');
end;
var j: TJSONObject;
begin
// получаем json класса, в котором могут быть или не быть TObjectList с ненужными нам парами
j := TJson.ObjectToJsonObject(Self);
// в этой процедуре очищаем полученный json от этих пар
ClearJsonObjectList(j);
// возвращаем результат в виде строки json
Result := j.ToString;
end;
(*
// example
// json before ClearJsonObjectList --------------->
{
"content":{
"checkClose":{
"payments":{
"ownsObjects":true, <<-- must be removed
"listHelper":[ <<-- must be removed
]
},
...
},
"positions":{
"ownsObjects":true, <<-- must be removed
"listHelper":[ <<-- must be removed
]
},
...
},
...
}
// json after ClearJsonObjectList --------------->
{
"content":{
"checkClose":{
"payments":{
},
...
},
"positions":{
},
...
},
...
}
*)
procedure ClearJsonObjectList(AJson: TJSONObject);
function GetAsObjectList(AJson: TJSONObject): TJSONPair;
var
ownsObjects, listHelper: TJSONPair;
begin
Result := nil;
if AJson.Count = 2 then
begin
ownsObjects := AJson.Get('ownsObjects');
listHelper := AJson.Get('listHelper');
if Assigned(ownsObjects) and Assigned(listHelper) then
if (ownsObjects.JsonValue is TJSONBool) and (listHelper.JsonValue is TJSONArray) then
begin
AJson.RemovePair(ownsObjects.JsonString.Value);
AJson.RemovePair(listHelper.JsonString.Value);
Result := listHelper;
end;
end;
end;
var
index: integer;
itemName: string;
itemValue: TJSONObject;
list: TJSONPair;
begin
for index := Pred(AJson.Count) downto 0 do
if AJson.Pairs[index].JsonValue is TJSONObject then
begin
itemValue := TJSONObject(AJson.Pairs[index].JsonValue);
list := GetAsObjectList(itemValue);
if Assigned(list) then
begin
itemName := AJson.Pairs[index].JsonString.Value;
AJson.RemovePair(itemName);
AJson.AddPair(itemName, list.JsonValue);
end
else
ClearJsonObjectList(itemValue);
end;
end;
5条答案
按热度按时间u1ehiz5o1#
您可以将
JsonReflect
属性放在字段上,并控制它们的序列化方式。下面是一些示例代码,说明如何编写专门的“将此对象列表序列化为数组”属性来处理此问题-只需将单位添加到uses中并将
[SerializeObjectList]
添加到字段中。字符串
不幸的是,相反的方式并不起作用,因为
TJSONUnMarshal.PopulateFields
内部似乎有一个bug,当试图从json字符串填充列表时会导致AV。kx5bkwkv2#
字符串
pkwftd7m3#
我建议你创建一个对象数组而不是列表,如果不是一般的话,那么为了序列化到JSON。这在JSON中效果更好,无论是阅读还是写。只要确保处理所涉及的内存,即释放列表中的对象,就像这样:
字符串
我通常把它放在我的 *.dpr文件中,只是为了确保:
型
lymgl2op4#
nikhil swami的解决方案的改进是:
字符串
vs3odd8k5#
字符串