如何隐藏"拥有对象"和" listHelper"使用Delphi(Rest.JSON)从Json获取TObjectList的属性?

时间:2018-02-01 15:59:20

标签: json delphi delphi-10.2-tokyo

我正在使用Delphi Tokyo尝试使用TJson将对象转换为json。 Rest.Json中存在ObjectToJsonString方法。 一个具有简单属性(如String或Integer)的简单对象可以,但是当添加属性TObjectList时,json会被属性" ownsObjects"和" listHelper",但WebService不接受这些字段。我怎样才能隐藏"它来自Json?

3 个答案:

答案 0 :(得分:2)

您可以将JsonReflect属性放在字段上并控制它们的序列化方式。

以下是一些示例代码,说明如何编写自己的专用"将此对象列表序列化为数组"需要注意的属性 - 只需将单位添加到使用中,然后将[SerializeObjectList]添加到您的字段中。

unit CollectionsReflect;

interface

uses
  Generics.Collections,
  REST.JsonReflect;

type
  SerializeObjectListAttribute = class(JsonReflectAttribute)
    constructor Create;
  end;

implementation

uses
  Rtti;

type
  TListOfObjectInterceptor = class(TJSONInterceptor)
    function ObjectsConverter(Data: TObject; Field: string): TListOfObjects; override;
  end;

{ TListOfObjectInterceptor }

function TListOfObjectInterceptor.ObjectsConverter(Data: TObject;
  Field: string): TListOfObjects;
var
  ctx: TRttiContext;
  list: TList<TObject>;
begin
  list := TList<TObject>(ctx.GetType(Data.ClassInfo).GetField(Field).GetValue(Data).AsObject);
  Result := TListOfObjects(list.List);
  SetLength(Result, list.Count);
end;

{ SerializeObjectListAttribute }

constructor SerializeObjectListAttribute.Create;
begin
  inherited Create(ctObjects, rtObjects, TListOfObjectInterceptor);
end;

end.

不幸的是,相反的方式不能以这种方式工作,因为TJSONUnMarshal.PopulateFields内部似乎有一个错误,当尝试从json字符串填充列表时会导致AV。

答案 1 :(得分:0)

    // 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":{
      },
      ...
    },
    ...
  }
*)

答案 2 :(得分:-1)

function TSrvMethContab.GetConecctions: TJSONObject;
var
 lContext : TDbContext ;
 lLista : TList<TConexions>;
 jResult : TJSONObject;
begin
  lContext := TDbContext.Create(strConexion);
  try
   lLista := lContext.Select<TConexions>();
   jResult := TJson.ObjectToJsonObject(lLista);
   jResult.RemovePair('listHelper');
   Result := jResult;
  finally
   lContext.Free;
 end;
end;