Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TDictionary to JSON und zurück (https://www.delphipraxis.net/185434-tdictionary-json-und-zurueck.html)

Yaso 10. Jun 2015 08:39

TDictionary to JSON und zurück
 
Hallo zusammen

Ich experimentiere gerade mit REST.JSON und das funktioniert ziemlich gut, aber hier habe ich ein Problem:

Ich möchte ein TDictionary<string,TEintragClass> in ein JSON String und zurück umwandeln. Das zurück geht aber leider noch nicht, da bringt er mir eine Exception:

Intern: Typ
System.Generics.Collections.TDictionary<...> kann nicht instantiiert werden.

Folgendes habe ich gemacht:
Delphi-Quellcode:
  TEintragClass = class
  private
    FOriginalFilename: string;
    FLastModified: TDateTime;
    FAnzahl: Integer;
    FStrings: TStringList;
  end;

procedure TForm8.Button1Click(Sender: TObject);
var
  Dict : TDictionary<string, TEintragClass>;
  Eintrag: TEintragClass;
  Liste: TStringList;
begin
  Liste := TStringList.Create();
  Eintrag := TEintragClass.Create();
  Dict := TDictionary<string,TEintragClass>.Create;
 
  Liste.Add('File1');
  Liste.Add('File2');
  Eintrag.FOriginalFilename := 'abc';
  Eintrag.FLastModified := Now();
  Eintrag.FAnzahl := 3;
  Eintrag.FStrings := Liste;
  Dict.Add('asd',Eintrag);
  Dict.Add('asd2',Eintrag);
  Memo1.Lines.Text := TJson.ObjectToJsonString(Dict);
 
  Dict.Free;
  Eintrag.Free;
  Liste.Free;
 
end;

procedure TForm8.Button2Click(Sender: TObject);
var
  Dict2 : TDictionary<string, TEintragClass>;
begin
  Dict2 := TJson.JsonToObject<TDictionary<string, TEintragClass>>(Memo1.Lines.Text); // Da knallts
  Dict2.Free;
end;
Was habe ich übersehen? :oops:

Dejan Vu 10. Jun 2015 08:51

AW: TDictionary to JSON und zurück
 
Mach doch aus der TDictionary<string, TEintragsClass> einen eigenen Datentypen und spendiere dem einen parameterlosen Konstruktor.
Vielleicht ist diese Json-Implementierung zu blöd, eine generische Klasse zu instantiieren (oder Delphi ist zu minderbemittelt, keine Ahnung).

himitsu 10. Jun 2015 09:16

AW: TDictionary to JSON und zurück
 
Wenn es an den < und > im Klassennamen geht, dann mal probieren das zu verstecken.
Delphi-Quellcode:
type
  TEintragDictionary = class(TDictionary<string, TEintragClass>)
  end;
Nur über den Klassentyp wäre es egal, ob Generic oder nicht, denn das merkt man dort nicht.

Yaso 10. Jun 2015 09:36

AW: TDictionary to JSON und zurück
 
Erst Mal Danke für die Tipps, aber leider schaffe ich es immer noch nicht, vielleicht mache ich auch was falsch (bin erst seit kurzem bei Delphi).

mit
Delphi-Quellcode:
  TEintragDictionary = class(TDictionary<string, TEintragClass>)
  end;
Kommt nun eine Zugriffsverletzung am gleichen Ort (...Lesen von von Adresse 00000000)

mit
Delphi-Quellcode:
TEintragDictionary = class(TDictionary<string, TEintragClass>)
  constructor Create();
end;

constructor TEintragDictionary.Create;
begin
  inherited
end;
Gibts die gleiche Exception schon beim Umwandeln in einen JSON String

Yaso 10. Jun 2015 11:50

AW: TDictionary to JSON und zurück
 
hmmm

Wenn ich
Delphi-Quellcode:
TDictionary<string, string>;
oder
Delphi-Quellcode:
TDictionary<string, Integer>;
mache, dann klappts wunderbar.

Es scheint, dass Delphi mit selber erstellten Objekten mühe hat.

Dejan Vu 10. Jun 2015 11:55

AW: TDictionary to JSON und zurück
 
Deine Klasse hat ja auch nix zum Serialisieren. Deklariere mal ein paar public properties.

himitsu 10. Jun 2015 11:55

AW: TDictionary to JSON und zurück
 
Steht denn im JSON-Text auch der Typname dieser Objekte mit drin?

Yaso 10. Jun 2015 12:06

AW: TDictionary to JSON und zurück
 
Als JSON String kommt mit dem Code aus dem Beitrag 1 folgender String heraus, welchen ich eigentlich auch wieder einlese und zurückwandeln möchte:
Code:
{
   "items": [[-1,
   "",
   null],
   [-1,
   "",
   null],
   [1975215994,
   "asd",
   {
      "originalFilename": "abc",
      "lastModified": "2015-06-10T13:02:31.491Z",
      "anzahl": 3,
      "strings": {
         "list": [["File1",
         null],
         ["File2",
         null],
         ["",
         null],
         ["",
         null]],
         "count": 2,
         "capacity": 4,
         "sorted": false,
         "duplicates": "dupIgnore",
         "caseSensitive": false,
         "ownsObject": false,
         "encoding": null,
         "defaultEncoding": {
            "codePage": 1252,
            "mBToWCharFlags": 0,
            "wCharToMBFlags": 0,
            "isSingleByte": true,
            "maxCharSize": 1
         },
         "delimiter": "",
         "lineBreak": "",
         "quoteChar": "",
         "nameValueSeparator": "",
         "strictDelimiter": false,
         "updateCount": 0,
         "writeBOM": true
      }
   }],
   [996913175,
   "asd2",
   {
      "originalFilename": "abc",
      "lastModified": "2015-06-10T13:02:31.491Z",
      "anzahl": 3,
      "strings": {
         "list": [["File1",
         null],
         ["File2",
         null],
         ["",
         null],
         ["",
         null]],
         "count": 2,
         "capacity": 4,
         "sorted": false,
         "duplicates": "dupIgnore",
         "caseSensitive": false,
         "ownsObject": false,
         "encoding": null,
         "defaultEncoding": {
            "codePage": 1252,
            "mBToWCharFlags": 0,
            "wCharToMBFlags": 0,
            "isSingleByte": true,
            "maxCharSize": 1
         },
         "delimiter": "",
         "lineBreak": "",
         "quoteChar": "",
         "nameValueSeparator": "",
         "strictDelimiter": false,
         "updateCount": 0,
         "writeBOM": true
      }
   }]],
   "count": 2,
   "growThreshold": 3,
   "keyCollection": null,
   "valueCollection": null
}
Also eigentlich alles vorhanden. Der Typname meiner Klasse wird dem REST.JsonReflect übergeben, der findet es aber, so wie ich es beim debuggen sehe, nicht.

Properties? Die werden soweit ich weiss ignoriert: http://blogs.embarcadero.com/stephen...-line-of-code/ (Siehe Response)

EDIT:
Habe es mit einem Property probiert alles andere auskommentiert > genau dasselbe Ergebnis

Yaso 15. Jun 2015 15:05

AW: TDictionary to JSON und zurück
 
Hab nun etwas herumprobiert:

Wenn ich beim Einlesen Ein Objekt nehme, scheint es zu funktionieren:

Delphi-Quellcode:
procedure TForm8.Button2Click(Sender: TObject);
var
  Dict2 : TDictionary<string, TObject>;
begin
  Dict2 := TJson.JsonToObject<TDictionary<string, TObject>>(Memo1.Lines.Text); // Da knallts
  Dict2.Free;
end;
Da habe ich im Debugger alle Informationen drin in diesem Object, aber natürlich keine Felder.

Kann ich nun Das
Delphi-Quellcode:
TObject
irgendwie elegant und einfach nach
Delphi-Quellcode:
TEintragClass
parsen ohne selber einen Parser dafür zu schreiben?
Also sprich
Delphi-Quellcode:
TDictionary<string, TObject>
nach
Delphi-Quellcode:
TDictionary<string, TEintragClass>


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:35 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