Jump to content

Recommended Posts

Hello,

 

I'm currently using RAD Studio 11.2 and just wondering why the standard Delphi Json library (Rest.Json or Data.DBXJsonReflect) is not able to serialize a TGUID value ?

Is this possible or I am missing something ?

It fails with an 'insufficient RTTI available to support this operation' error.

Sure I can add a converter, but it should at least be converted as a record (or to a string), or no ?

 

How should this be handled ?

 

Thanks !

Frederic

Share this post


Link to post

TGUID contains this field: D4: array[0..7] of Byte; which does not emit typeinfo for its type

 

You can see this with the following code:

uses
  System.Rtti;
var
  ctx: TRttiContext;
begin
  var t := ctx.GetType(TypeInfo(TGUID));
  for var f in t.GetFields do
    Writeln(f.ToString);
  readln;
end.

The issue (not specifically for TGUID) is reported: https://quality.embarcadero.com/browse/RSP-27329

 

Now even if the RTTI would be available it would serialize TGUID in some format that is most likely not desired. However TGUID <-> string serialization should be supported out of the box imo.

Edited by Stefan Glienke
  • Like 1

Share this post


Link to post

Hi Stefan,

 

Thanks for pointing to the QC Issue.

I've just put an JSONReflect attribute on the concerned fields of my objects so now it works like I need.

OK the undesired format in one thing but yes it should produce something out of the box.

The output format can already be adjusted case by case, or possibly an option to choose the output format.


Regards

Share this post


Link to post
5 hours ago, Stefan Glienke said:

However TGUID <-> string serialization should be supported out of the box imo.

As I cannot spot one, do you happen to have a QP report at hand? Otherwise I will create one.

 

40 minutes ago, Frédéric said:

I've just put an JSONReflect attribute on the concerned fields of my objects

It would be nice if you can post the source here, unless you opt for creating that QP entry yourself.

Share this post


Link to post

Already wrote it: https://www.delphipraxis.net/208147-json-serializer-und-guid.html

 

IMO the solution with the converter has the benefit that you don't need to pollute all your classes with these unnecessary attributes.

I guess when using the REST unit there is no way to pass a converter to the underlying serializer/reader/write - the entire architecture is a huge clusterf**k.

Edited by Stefan Glienke
  • Thanks 1

Share this post


Link to post
39 minutes ago, Uwe Raabe said:

It would be nice if you can post the source here

Yes, of course! Here the code snippet:

 

interface

uses

 REST.JsonReflect;

type
  TGUIDInterceptor = class(TJSONInterceptor)
  public
    constructor Create;
    function  StringConverter(Data: TObject; Field: string): string; override;
    procedure StringReverter(Data: TObject; Field: string; Arg: string); override;
  end;

  MyClass = class(TObject)
  private
    [JSONReflect(ctString, rtString, TGUIDInterceptor, nil, true)]
    FJobUID: TGUID;
  published
    property  JobUID: TGUID read FJobUID write FJobUID;
  End;

implementation

uses System.Rtti;

{ TGUIDInterceptor }

constructor TGUIDInterceptor.Create;
begin
  inherited Create;
  ConverterType := ctString;
  ReverterType := rtString;
end;

function TGUIDInterceptor.StringConverter(Data: TObject; Field: string): string;
var
  ctx: TRTTIContext;
begin
  Result := GUIDToString(ctx.GetType(Data.ClassType).GetField(Field).GetValue(Data).AsType<TGUID>);
end;

procedure TGUIDInterceptor.StringReverter(Data: TObject; Field, Arg: string);
var
  ctx: TRTTIContext;
  LValue: TValue;
begin
  var vGUID := StringToGUID(Arg);
  TValue.Make<TGUID>(vGUID, LValue);
  ctx.GetType(Data.ClassType).GetField(Field).SetValue(Data, LValue);
end;

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×