Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi JSON To Object Problem (https://www.delphipraxis.net/207640-json-object-problem.html)

Samashy 17. Apr 2021 10:32

JSON To Object Problem
 
Hallo, ich hoffe jemand kann mir weiterhelfen, ich stelle mich einfach zu prasselig an.
Ich habe ein JSON, welches ich gern in ein Object giessen möchte:
Code:
{"energyDetails": {
   "timeUnit": "YEAR",
   "unit": "Wh",
   "meters":   [
            {
         "type": "Production",
         "values": [         {
            "date": "2021-01-01 00:00:00",
            "value": 569863
         }]
      },
            {
         "type": "FeedIn",
         "values": [         {
            "date": "2021-01-01 00:00:00",
            "value": 285170
         }]
      },
            {
         "type": "SelfConsumption",
         "values": [         {
            "date": "2021-01-01 00:00:00",
            "value": 284693
         }]
      },
            {
         "type": "Purchased",
         "values": [         {
            "date": "2021-01-01 00:00:00",
            "value": 31557
         }]
      },
            {
         "type": "Consumption",
         "values": [         {
            "date": "2021-01-01 00:00:00",
            "value": 316250
         }]
      }
   ]
}}
Mein Objektc habe ich so aufgebaut:
Code:
 TValues = class
   private
         [JSONName('date')]
        Fdate: String;
         [JSONName('value')]
        Fvalue: Integer;
 published
      property date :String read Fdate write Fdate;
      property value :Integer read Fvalue write Fvalue;
 end;

 TMeters = class
   private
        [JSONName('type')]
       Ftype: String;
        [JSONName('values')]
       Fvalues: TValues;
   published
       property types : String read Ftype write Ftype;
       property values : TValues read Fvalues write Fvalues;
 end;

 TEnergyDetails = class
  private
      [JSONName('timeUnit')]
     FtimeUnit :String;
      [JSONName('unit')]
     Funit    :String;
      [JSONName('meters')]
     Fmeters  :TObjectList<Tmeters>;
  published
     property timeUnit : String read FtimeUnit write FtimeUnit;
     property units   : String read Funit write Funit;
     property meters  : TObjectList<Tmeters> read Fmeters write Fmeters;
 end;
Die Umwandlung wollte ich so machen:
Code:
  memo1.Text :=RESTResponse1.JSONValue.ToJSON;
        energyDetail:= TJson.JsonToObject<TEnergyDetails>(memo1.Text);
        listbox1.Items.Add(energyDetail.timeUnit);
        listbox1.Items.Add(energyDetail.units);
Es entsteht das Object, aber ist komplett leer. :(
('', '', nil)
Ich steh völlig auf dem Schlauch.

Kann mir bitte jemand den erhellenden Hinweis geben?

Danke,
Romy

Uwe Raabe 17. Apr 2021 10:46

AW: JSON To Object Problem
 
  1. values ist ein Array
  2. meters ebenso (arrays sind keine TObjectList)

Die JsonName-Attribute kannst du weglassen, wenn das Feld lediglich dem Json-Namen mit vorangestellten F entspricht (value -> FValue). Dabei kann der Buchstabe nach dem F auch großgeschrieben werden.

Versuch's mal so:
Delphi-Quellcode:
type
  TValue = class
  private
    Fdate: string;
    Fvalue: Integer;
  published
    property date: string read Fdate write Fdate;
    property value: Integer read Fvalue write Fvalue;
  end;
  TValues = TArray<TValue>;

  TMeter = class
  private
    Ftype: string;
    Fvalues: TValues;
  public
    destructor Destroy; override;
  published
    property types: string read Ftype write Ftype;
    property values: TValues read Fvalues write Fvalues;
  end;
  TMeters = TArray<TMeter>;

  TEnergyDetails = class
  private
    FtimeUnit: string;
    Funit: string;
    Fmeters: TMeters;
  public
    destructor Destroy; override;
  published
    property timeUnit: string read FtimeUnit;
    property units: string read Funit;
    property meters: TMeters read Fmeters;
  end;

implementation

destructor TMeter.Destroy;
var
  I: Integer;
begin
  for I := 0 to Length(FValues) - 1 do
    FValues[I].Free;
  inherited;
end;

destructor TEnergyDetails.Destroy;
var
  I: Integer;
begin
  for I := 0 to Length(Fmeters) - 1 do
    Fmeters[I].Free;
  inherited;
end;
Wenn du TObjecList für ein Json-Array verwenden willst empfehle ich diesen Artikel: Serializing Generic Object Lists with TJson

Uwe Raabe 17. Apr 2021 10:53

AW: JSON To Object Problem
 
Fehlt noch was:
Delphi-Quellcode:
  TWrapper = class
  private
    { wrapper ist nicht owner! }
    FEnergyDetails: TEnergyDetails;
  public
    property EnergyDetails: TEnergyDetails read FEnergyDetails;
  end;
Aufruf dann so:
Delphi-Quellcode:
  memo1.Text :=RESTResponse1.JSONValue.ToJSON;
  wrapper:= TJson.JsonToObject<TWrapper>(memo1.Text);
  try  
    energyDetail := wrapper.EnergyDetails;
  finally
    wrapper.Free;
  end;
  listbox1.Items.Add(EnergyDetail.timeUnit);
  listbox1.Items.Add(EnergyDetail.units);

Samashy 17. Apr 2021 11:11

AW: JSON To Object Problem
 
Danke für Deine Hilfe.

Ich habe Deinen Vorschlag erst Mal übernommen, aber es funktioniert noch nicht.

Code:
'{"energyDetails":{"timeUnit":"YEAR","unit":"Wh","meters":[{"type":"Purchased","values":[{"date":"2021-01-01 00:00:00","value":31557.0}]},{"type":"SelfConsumption","values":[{"date":"2021-01-01 00:00:00","value":284693.0}]},{"type":"FeedIn","values":[{"date":"2021-01-01 00:00:00","value":285170.0}]},{"type":"Production","values":[{"date":"2021-01-01 00:00:00","value":569863.0}]},{"type":"Consumption","values":[{"date":"2021-01-01 00:00:00","value":316250.0}]}]}}'
Ich dachte jetzt schon das mein
Code:
memo1.Text :=RESTResponse1.JSONValue.ToJSON;
das Problem ist und habe eine STRING Variable als Test probiert

Code:
teststring :=RESTResponse1.JSONValue.ToJSON;
     energyDetail:= TJson.JsonToObject<TEnergyDetails>(teststring);
War aber nicht das Problem :(
Das Object bleibt leer, aber dank Deiner Hilfe sind die "meters" nicht mehr nil. -> ('', '', ())

Hab ich mein Object nicht richtig für das JSON vorbereitet?

Danke, Romy

Samashy 17. Apr 2021 11:18

AW: JSON To Object Problem
 
OMG wie cool, es geht.

Tausend Dank. :-D
Romy


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