Как сериализовать TList‹T› в Json без мусора

Мне нужно сериализовать этот json-укус в класс Delphi.

  {
    "Master":{
      "version":"1.0"
    },
    "Details":[
      {
        "idColisEntreeDetail":0,
        "codeBarre":"123456789"
      },
      {
        "idColisEntreeDetail":0,
        "codeBarre":"234567890"
      }
    ]
  }

Вот мой класс:

unit unit2;

interface

uses Generics.Collections, Rest.Json;

type

  TDetails = class
  private
    FCodeBarre: String;
    FIdColisEntreeDetail: Extended;
  public
    property codeBarre: String read FCodeBarre write FCodeBarre;
    property idColisEntreeDetail: Extended read FIdColisEntreeDetail
      write FIdColisEntreeDetail;
  end;

  TMaster = class
  private
    FVersion: String;
  public
    property version: String read FVersion write FVersion;
  end;

  TMyClass = class
  private
    FDetails: TList<TDetails>;
    FMaster: TMaster;
  public
    property Details: TList<TDetails> read FDetails write FDetails;
    property Master: TMaster read FMaster write FMaster;
    constructor Create;
    destructor Destroy; override;
  end;

implementation

{ TDetails }


{ TMyClass }

constructor TMyClass.Create;
begin
  inherited;
  FMaster := TMaster.Create();
end;

destructor TMyClass.Destroy;
var
  LDetailsItem: TDetails;
begin

  for LDetailsItem in FDetails do
    LDetailsItem.free;

  FMaster.free;
  inherited;
end;

end.

Я использую TJson.ObjectToJsonString(TMyClass) и TJson.JsonToObject<TMyClass>(AJsonString).

Моя проблема в том, что при сериализации типа TList<TDetails> генерируется много мусора. Например

  {
    "details":{
      "items":[
      {
        "idColisEntreeDetail":0,
        "codeBarre":"123456789"
      },
      {
        "idColisEntreeDetail":0,
        "codeBarre":"234567890"
      }
      ],
      "count":2,
      "arrayManager":{
      }
    },
    "master":{
      "version":""
    }
  }

Вместо этого можно использовать тип TArray<TDetails>, но я потеряю все функции TList.

Как я могу использовать тип TList и получить правильный вывод Json?


person Stephane Wierzbicki    schedule 26.03.2015    source источник
comment
Я бы сериализовал это вручную.   -  person David Heffernan    schedule 26.03.2015
comment
Просто, не используйте TJson.ObjectToJsonString и TJson.JsonToObject, это дерьмо, поскольку они просто тупо сериализуют каждое поле.   -  person Stefan Glienke    schedule 26.03.2015
comment
Стефан Глиенке, есть ли альтернатива?   -  person Stephane Wierzbicki    schedule 26.03.2015
comment
@StefanGlienke В общем, как функция общего назначения может знать, что нужно сериализовать? Автор класса должен сообщить сериализатору, что нужно делать, а что нет.   -  person David Heffernan    schedule 26.03.2015
comment
Думаю, у этого есть сериализатор: github.com/ahausladen/JsonDataObjects   -  person FMXExpress    schedule 26.03.2015
comment
@DavidHeffernan Delphi опубликовал директиву для маркировки свойств, которые должны быть сериализованы. Почему это не было использовано в качестве отправной точки в сериализации JSON, мне непонятно.   -  person Dalija Prasnikar    schedule 26.03.2015
comment
@DalijaPrasnikar Ну, а что, если вы хотите, чтобы участник был менее чем общедоступным, но его нужно сериализовать?   -  person David Heffernan    schedule 26.03.2015
comment
@DavidHeffernan Мне еще предстоит найти пример такого в реальном мире. Если что-то не предназначено для публики, то это, конечно, не нужно сериализовать.   -  person Dalija Prasnikar    schedule 26.03.2015
comment
@DalijaPrasnikar В моем коде много таких примеров.   -  person David Heffernan    schedule 26.03.2015
comment
@DavidHeffernan Я не хочу вступать в дискуссию о коде. Что мне ясно, так это то, что в Delphi публикуется маркер для сериализации, есть также другие средства для определения данных, которые должны быть сериализованы (DefineBinaryProperty), то есть инфраструктура, которую нужно было использовать в качестве основы, а не что-то совершенно выходящее за рамки соответствует тому, как работает Delphi.   -  person Dalija Prasnikar    schedule 26.03.2015
comment
@DalijaPrasnikar Проблема в том, что публикация влияет не только на сериализацию.   -  person David Heffernan    schedule 26.03.2015
comment
@DavidHeffernan Я не уверен, что следую ... если он общедоступен, то публикация влияет только на сериализацию (если вы не делали каких-то других странных вещей), если он не общедоступен, то есть другие средства определения данных для сериализации ... сбрасывание всего создает серьезные проблемы и несовместимо с миллионами классов Delphi.   -  person Dalija Prasnikar    schedule 26.03.2015
comment
@DalijaPrasnikar Я высказал свою точку зрения. Сериализация и видимость должны быть разделены.   -  person David Heffernan    schedule 26.03.2015
comment
@DavidHeffernan Возможно, их следует разделить, но в Delphi они никогда не разделялись. Две ошибки не делают его правильным.   -  person Dalija Prasnikar    schedule 26.03.2015
comment
@Dalija Сериализация требует тонкого контроля. Атрибуты — это путь вперед.   -  person David Heffernan    schedule 26.03.2015
comment
Это то, что поддерживает TJSONMarshal (задается, например, в this post). Не знаю, как насчет TJson, но я ожидаю там подобного подхода.   -  person TLama    schedule 27.03.2015
comment
ObjectsMappers, содержащиеся в DelphiMVCFramework, могут делать такие вещи довольно просто.   -  person Daniele Teti    schedule 29.03.2015
comment
@TLama Проблема с атрибутами заключается в том, что вы не можете внедрить атрибут в класс вне вашего контроля, как в этом случае TList.   -  person Dalija Prasnikar    schedule 29.03.2015