AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Json Serializer und GUID

Ein Thema von backdraft · begonnen am 18. Jun 2021 · letzter Beitrag vom 18. Jun 2021
 
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
3.079 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Json Serializer und GUID

  Alt 18. Jun 2021, 10:55
Es liegt, wie jaenicke andeutet, an der Typ-Definition für D4.
Das array[0..7] of Byte bekommt die Rtti nicht als Typ aufgedröselt.
Vielleicht ein Bug, weil anscheinend die Rtti immer einen richtigen Alias-Namen braucht.
Beim Erstellen des notwendigen TRttiField für D4, wird der FFieldType nicht ordentlich aufgelöst.
Die PTypeInfo dafür müsste als TTypeKind.tkArray rauskommen.
Delphi-Quellcode:
constructor TRttiField.Create(APackage: TRttiPackage; AParent: TRttiObject;
  var P: PByte);
begin
  inherited Create(APackage, AParent, P);
  FFieldType := GetFieldType; // hier kommt nil zurück für statische Arrays.
  FOffset := GetOffset;
end;
...
function TRttiRecordField.GetFieldType: TRttiType;
begin
  Result := Pool.TypeOrNil(Handle^.Field.TypeRef); //TypeRef ist hier nil, daher kommt von TypeOrNil auch nichts zurück. Das passiert schon beim Erzeugen des Basis-Typs TRttiObject im constructor
end;
Darum ist in TJsonSerializerWriter.WriteProperty in Zeile 1361 AProperty.Contract := ResolveContract(AProperty.TypeInf); der Wert für AProperty.TypeInf nil und es kommt kein vernünftiger Contract: TJsonContract bei raus.

Du kannst dich zumindest dahingehend behelfen, indem du dir einen Hilftyp zusammen schusterst und später dann immer zwischen deinen GUID-Typ und den richtigen TGUID-Typ aus der RTL castest:

Konsolenbeispiel:
Delphi-Quellcode:
program Project6;

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

uses
    System.SysUtils,
    System.Classes,
    System.JSON,
    System.JSON.Serializers;

type
    // TMyGUID = TGUID;
    TMyArray = array [0 .. 7] of Byte;

    TMyGUID = record
    public
        D1: Cardinal;
        D2: Word;
        D3: Word;
        D4: TMyArray;
        class function NewGuid: TMyGUID; static;
        function ToString: string;
    end;

class function TMyGUID.NewGuid: TMyGUID;
var
    foo: TGUID;
begin
    foo := TGuid.NewGuid;
    Result.D1 := foo.D1;
    Result.D2 := foo.D2;
    Result.D3 := foo.D3;
    Result.D4 := TMyArray(foo.D4);
end;

function TMyGUID.ToString: string;
begin
    Result := TGuid(Self).Tostring;
end;

var
    lGuid, lNewGuid: TMyGUID;
    lText: TStringList;
    lJson: string;
    lSerializer, lDeserializer: TJsonSerializer;

begin
    try
        lText := TStringList.Create;
        try
            lGuid := TMyGUID.NewGuid;
            lText.Add(lGuid.ToString);

            lSerializer := TJsonSerializer.Create;
            try
                lJson := lSerializer.Serialize<TMyGUID>(lGuid);
            finally
                FreeAndNil(lSerializer);
            end;

            lText.Add(lJson);

            lDeserializer := TJsonSerializer.Create;
            try
                lNewGuid := lDeserializer.Deserialize<TMyGUID>(lJson);
            finally
                FreeAndNil(lSerializer);
            end;

            lText.Add(lNewGuid.ToString);

            Writeln(lText.Text);
        finally
            FreeAndNil(lText);
        end;
    except
        on E: Exception do
            Writeln(E.ClassName, ': ', E.Message);
    end;
    Readln;
end.
Über den Call Stack TJsonDefaultContractResolver.ResolveContract | TJsonDefaultContractResolver.CreateContract | TJsonDefaultContractResolver.CreateArrayContract wird eine Instanz von TJsonArrayContract erzeugt, mit der die Serialisierung arbeiten kann.
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:03 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz