Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   JSON in Delphi (https://www.delphipraxis.net/204113-json-delphi.html)

Incocnito 24. Apr 2020 14:26

JSON in Delphi
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Zusammen,

ich versuche das mal als Beispiel zusammenzufassen, also bitte nicht meckern, wenn nun vieles fehlt oder sinnlos erscheint, weil leer.

1) Ich habe ein JSON:
Code:
{
  "links": {
    "start": "bla",
    "xxx": "yyy",
    "zzz": "nnn"
  },
  "data": {
    "type": "wertA",
    "id": "wertB"
  },
  "included": [
    {
      "type": "wert1",
      "id": "wert2"
    }
  ]
}
Davon brauche ich aber nur "links", außerdem kann ich verschiedene JSON bekommen, aber "links" ist immer dabei. Also dachte ich mir "mache einfach eine class mit nur "links":
Delphi-Quellcode:
  type T2 = class
    FStart : String;
    FXxx  : String;
    FZzz  : String;
  end;
  type T1 = class
  private
    FLinks : T2;
  end;
dazu passen sage ich dann:
Delphi-Quellcode:
TempRes := TJSON.JsonToObject<T1>(sContent);
Hier fliegt er dann raus in REST.JSonReflect in
procedure TJSONUnMarshal.PopulateFields(JsonFields: TJSONObject; Data: TObject;
JsonCustomizer: TJSONPopulationCustomizer);
in Zeile 2969
Delphi-Quellcode:
        else if jsonFieldVal is TJSONArray then
        begin
          rField := GetFieldType(Data, FieldName);
          // Unmarshal TList<T>.FListHelper as dynamic array using 10.2 layout
          if (rField.FieldType.Handle = TypeInfo(System.Generics.Collections.TListHelper)) and // <- Hier
             (I < JsonFields.Count - 1) and
             (string.CompareText('listHelper', FieldName) = 0) and
             (string.CompareText('items', JsonFields.Pairs[I + 1].JsonString.Value) = 0) then
          begin
denn GetFieldType(Data, FieldName); gibt bei FieldName "included" den Wert "nil" zurück.
(Habe das Bild aus dem Debugger auch mal als Json_Err.jpg angehangen!)

Ich hoffe das ist irgendwie verständlich geschrieben.

Ist das ein bekannter Delphi-Fehler? Das wenn das letzte Objekt ein Array ist,
dass man die Klasse dann nicht kürzen kann oder sowas?
Ist es nicht möglich eine Klasse zu kürzen? Was wenn ich von einer Stelle ein Json bekomme
und irgendwann hängen die schonmal was an, ohne dass ich das mitbekomme?
Dann fliegt mir das Programm um die Ohren?

Hatte jemand das auch schonmal und kann das Verhalten bestätigen?

Nutzt ihr andere JSon-Parser, welche schneller/besser/toller sind,
oder in diesem Fall gar "Fehlerfrei" (falls ich selbst nicht einen Denkfehler drin habe)?

Vielen Dank schonmal für die Zeit!

Liebe Grüße
Incocnito

DeddyH 24. Apr 2020 15:00

AW: JSON in Delphi
 
Da mir dieses ganze Marshalling in Delphi immer etwas suspekt ist, mache ich sowas von Hand.
Delphi-Quellcode:
uses ..., System.JSON;

type
  TLinks = class
  private
    FStart: string;
    Fxxx: string;
    Fzzz: string;
  public
    class function FromJSON(const Obj: TJSONObject): TLinks; overload; static;
    class function FromJSON(const ObjStr: string): TLinks; overload; static;
    property Start: string read FStart write FStart;
    property xxx: string read Fxxx write Fxxx;
    property zzz: string read Fzzz write Fzzz;
  end;

...

class function TLinks.FromJSON(const Obj: TJSONObject): TLinks;
var
  Value: TJSONValue;
  lObj: TJSONObject;
  Dummy: string;
begin
  Result := nil;
  if Assigned(Obj) then
    begin
      Value := Obj.Values['links'];
      if Assigned(Value) and (Value is TJSONObject) then
        begin
          lObj := TJSONObject(Value);
          Result := TLinks.Create;
          if lObj.TryGetValue<string>('start', Dummy) then
            Result.Start := Dummy;
          if lObj.TryGetValue<string>('xxx', Dummy) then
            Result.xxx := Dummy;
          if lObj.TryGetValue<string>('zzz', Dummy) then
            Result.zzz := Dummy;
        end;
    end;
end;

class function TLinks.FromJSON(const ObjStr: string): TLinks;
var
  Obj: TJSONObject;
begin
  Obj := TJSONObject.ParseJSONValue(ObjStr) as TJSONObject;
  try
    Result := TLinks.FromJSON(Obj);
  finally
    Obj.Free;
  end;
end;

Uwe Raabe 24. Apr 2020 17:03

AW: JSON in Delphi
 
Welche Delphi Version benutzt du denn? Bei mir (10.3.3) ist das eine andere Zeilennummer und da steht:
Delphi-Quellcode:
          rField := GetFieldType(Data, FieldName);
          // Unmarshal TList<T>.FListHelper as dynamic array using 10.2 layout
          if (rField <> nil) and
             (rField.FieldType.Handle = TypeInfo(System.Generics.Collections.TListHelper)) and
Damit sollte der Fehler nicht auftauchen.

Incocnito 27. Apr 2020 06:52

AW: JSON in Delphi
 
Zitat:

Zitat von DeddyH (Beitrag 1462831)
Da mir dieses ganze Marshalling in Delphi immer etwas suspekt ist, mache ich sowas von Hand....

Dein Ernst? Bei den ganzen Json, die wir nutzen wären wir ewig zu gange das alles auch noch von Hand zu machen! :shock:

Zitat:

Zitat von Uwe Raabe (Beitrag 1462838)
Welche Delphi Version benutzt du denn? Bei mir (10.3.3) ist das eine andere Zeilennummer und da steht:
Delphi-Quellcode:
          rField := GetFieldType(Data, FieldName);
          // Unmarshal TList<T>.FListHelper as dynamic array using 10.2 layout
          if (rField <> nil) and
             (rField.FieldType.Handle = TypeInfo(System.Generics.Collections.TListHelper)) and
Damit sollte der Fehler nicht auftauchen.

Was soll ich sagen: 10.3.2 ... dann ist das wohl ein Delphi-Bug, den die selbst schon behoben haben, ja?
Dann heißt es mal wieder: auf zum nächsten Update!

Danke für die Hilfe!
Liebe Grüße
Incocnito

Uwe Raabe 27. Apr 2020 07:49

AW: JSON in Delphi
 
Zitat:

Zitat von Incocnito (Beitrag 1462945)
Was soll ich sagen: 10.3.2 ... dann ist das wohl ein Delphi-Bug, den die selbst schon behoben haben, ja?

Access violation in TJSONUnMarshal.PopulateFields if array does not exist in target object

Sherlock 27. Apr 2020 14:17

AW: JSON in Delphi
 
Zitat:

Zitat von Incocnito (Beitrag 1462945)
Zitat:

Zitat von DeddyH (Beitrag 1462831)
Da mir dieses ganze Marshalling in Delphi immer etwas suspekt ist, mache ich sowas von Hand....

Dein Ernst? Bei den ganzen Json, die wir nutzen wären wir ewig zu gange das alles auch noch von Hand zu machen! :shock:

Das dauert weniger lange als Du denkst, wenn man zwei Punkte beachtet: man unterstützt zunächst kein Allerwelts-JSON, sondern ein sehr spezielles von einem Anbieter. Wenn man das erweiterbar implementiert, ist man sehr zügig mit weiteren Anbietern durch.

Sherlock


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz