3

I need to serialize this json sting to an Delphi class.

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

Here is my class:

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.

I'm using TJson.ObjectToJsonString(TMyClass) and TJson.JsonToObject<TMyClass>(AJsonString).

My problem is that a lot of garbage is generated when serializing an TList<TDetails> type. For example

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

It's fine when using an TArray<TDetails> type instead but I'll loose all TList feature.

How can I still use TList type and get a correct Json output ?

Sir Rufo
  • 18,395
  • 2
  • 39
  • 73
  • I'd serialise this manually. – David Heffernan Mar 26 '15 at 10:55
  • 2
    Simple, don't use `TJson.ObjectToJsonString` and `TJson.JsonToObject`, they are crap as they just stupidly serialize every field. – Stefan Glienke Mar 26 '15 at 12:49
  • Stefan Glienke, is there any alternative ? – Stephane Wierzbicki Mar 26 '15 at 12:57
  • 1
    @StefanGlienke In general, how can a general purpose function know what needs to be serialized? The author of the class needs to tell the serializer what needs to go, and what doesn't. – David Heffernan Mar 26 '15 at 13:04
  • This has a serializer I think: https://github.com/ahausladen/JsonDataObjects – FMXExpress Mar 26 '15 at 13:30
  • 1
    @DavidHeffernan Delphi has published directive for marking properties that have to be serialized. Why that wasn't used as starting point in JSON serialization is beyond me. – Dalija Prasnikar Mar 26 '15 at 13:34
  • @DalijaPrasnikar Well, what if you want to have a member with less than public visibility, but that needs to be serialized? – David Heffernan Mar 26 '15 at 13:35
  • @DavidHeffernan I have yet to find real world example of such thing. If something is not meant for public then it certainly does not need to be serialized. – Dalija Prasnikar Mar 26 '15 at 13:45
  • [List of bug reports covering JSON serialization in QP](https://quality.embarcadero.com/browse/RSP-9639?jql=text%20~%20%22JSON%22) – Dalija Prasnikar Mar 26 '15 at 13:47
  • 1
    @DalijaPrasnikar I've got plenty of such examples in my code. – David Heffernan Mar 26 '15 at 14:02
  • @DavidHeffernan I don't want to enter into discussion about code. What is clear to me is that in Delphi published is marker for serialization, there are also other means for defining data that has to be serialized (`DefineBinaryProperty`), that is infrastructure that had to be used as foundation, and not something completely out of the line with the way Delphi does things. – Dalija Prasnikar Mar 26 '15 at 18:57
  • @DalijaPrasnikar The problem is that published affects more than serialization. – David Heffernan Mar 26 '15 at 19:02
  • @DavidHeffernan I am not sure that I follow... if it is public, then published affects only serialization (unless you have been doing some other weird things), if it is not public, then there are other means of defining data for serialization... dumping everything creates serious problems and is incompatible with millions of Delphi classes out there. – Dalija Prasnikar Mar 26 '15 at 19:07
  • @DalijaPrasnikar I've made my point. Serialization and visibility should be separated. – David Heffernan Mar 26 '15 at 19:10
  • @DavidHeffernan Maybe they should be separated, but they were never separated in Delphi. Two wrongs does not make it right. – Dalija Prasnikar Mar 26 '15 at 19:11
  • 1
    @Dalija Serialization requires fine grained control. Attributes are the way forward. – David Heffernan Mar 26 '15 at 19:21
  • That's what the `TJSONMarshal` supports (asked e.g. in [`this post`](http://stackoverflow.com/q/10083967/960757)). Don't know how about `TJson`, but I would expect a similar approach there. – TLama Mar 26 '15 at 21:02
  • 1
    The ObjectsMappers contained into the DelphiMVCFramework can do this kind of things quite simply. – Daniele Teti Mar 29 '15 at 06:35
  • @TLama Problem with attributes is that you cannot inject attribute into class out of your control, like `TList` is in this case. – Dalija Prasnikar Mar 29 '15 at 14:35

0 Answers0