Frédéric 0 Posted January 31, 2023 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
Stefan Glienke 2002 Posted January 31, 2023 (edited) 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 January 31, 2023 by Stefan Glienke 1 Share this post Link to post
Frédéric 0 Posted January 31, 2023 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
Uwe Raabe 2057 Posted January 31, 2023 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
Stefan Glienke 2002 Posted January 31, 2023 (edited) 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 January 31, 2023 by Stefan Glienke 1 Share this post Link to post
Frédéric 0 Posted January 31, 2023 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
Uwe Raabe 2057 Posted February 2, 2023 https://quality.embarcadero.com/browse/RSP-40496 Share this post Link to post