Issue with difference between Delphi XE4 and XE7 JSON marshalling of TPointF type

1.2k views Asked by At

I am in the process of upgrading a project that was originally coded with Delphi XE4 using the new XE7 version. This application saves its main output as a marshaled JSON file that the users load, edit, save similar to what would be done with a Word document.

They do not work directly with the json, it is just used as the file format. The issue I am having is XE7 outputs the type TPointF differently than XE4 which causes an issue when trying to unmarshall.

This would not be an issue if I only had to handle opening files created with the new version but I have to support the old version files for at least a year. It looks like XE7 outputs all the possible fields in TPointF record (it is a variant record type)

Below is an example of the XE7 output

Using TJsonValue and TJsonMarshal:

{
  "type":"tstMnfHole.TmnfHole",
  "id":1,
  "fields":
  {
    "fctrPoint":
    [
      [0.625,132.5],
      0.625,
      132.5
    ]
  }
}

Using rest.json TJson.ObjectToJsonString(myHole)

{
  "ctrPoint":
  [
    [0.625,132.5],
    0.625,
    132.5
  ]
}

Below is an example of the XE4 output

Using TJsonValue and TJsonMarshal:

{
  "type":"tstMnfHole.TmnfHole",
  "id":1,
  "fields":
  {
    "fctrPoint":[0.625,132.5]
  }
}

My questions are:

  1. Is there a simple way to handle this with out having to override the default marshalling and create a custom converter/reverter so that the XE7 version outputs the same as XE4?
  2. Is this worth posting on Embarcadero Quality Central?

small console test app for both XE4 and XE7.


XE7


program testPointf;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  System.Types,
  // rest.json,
  data.dbxjsonReflect,
  //data.dbxjson,
  system.json,
  tstMnfHole in 'tstMnfHole.pas';

var
  myHole:  TmnfHole;
  valJson: TJSONValue;
  Marshal: TJSONMarshal;
begin
  try
    {*** Create new test hole ***}
    myHole      := TmnfHole.Create(0.625, 132.5);
    try
      Marshal   := TJSONMarshal.Create(TJSONConverter.Create);
      try
        valJson := Marshal.Marshal(myHole);
        try
          Writeln(valJson.ToString);
        finally
          valJson.Free;
        end;
      finally
        Marshal.Free;
      end;
    finally
      myHole.Free;
    end;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

unit tstMnfHole;

interface

uses system.types;

type
  TmnfHole = class(TObject)
    //...
    fctrPoint:  TPointF;
    constructor create; overload;
    constructor create(thisCtrPoint: TPointF); overload;
    constructor create(thisX, thisY: single); overload;
    //...
  end;

implementation

{ TmnfHole }
constructor TmnfHole.create;
begin
  fctrPoint := TPointF.Create(0.75, 120.50);
end;

constructor TmnfHole.create(thisCtrPoint: TPointF);
begin
  fctrPoint := TPointF.Create(thisCtrPoint.X, thisCtrPoint.Y);
end;

constructor TmnfHole.create(thisX, thisY: single);
begin
  fctrPoint := TPointF.Create(thisX, thisY);
end;

end.


XE4


testPointf.dpr: replace system.json with data.dbxjson

0

There are 0 answers