![]() |
AW: ObjectList serialisieren JSON
Zitat:
Trotzdem habe ich dabei aber immer noch ein Problem wenn ein Object meiner ObjectList auch eine ObjectList hat. Da krieg ich beim TConvert.FromJSON eine Zugriffsverletzung. Zum Beispiel, wenn wir Firma noch dazu nehmen, also eine Firma die mehrere Personen enthält. TFirmaList.TFirma.TPersonList.TPerson |
AW: ObjectList serialisieren JSON
Funktioniert doch tadellos.
Delphi-Quellcode:
type
TPerson = class private FName: String; public property Name: String read FName write FName; end; JsonObjectListPersonAttribute = class(JsonObjectListAttribute<TPerson>); type [JsonObjectListPerson] TPersonList = class(TObjectList<TPerson>) end; type TFirma = class private FName: string; [JSONOwned(False)] FPersonList: TPersonList; public constructor Create; destructor Destroy; override; property Name: string read FName write FName stored False; property PersonList: TPersonList read FPersonList write FPersonList; end; JsonObjectListFirmaAttribute = class(JsonObjectListAttribute<TFirma>); type [JsonObjectListFirma] TFirmaList = class(TObjectList<TFirma>) end; type { Wrapper } TWrapper = class private [JSONOwned(False)] FList: TFirmaList; public constructor Create; destructor Destroy; override; property List: TFirmaList read FList write FList; end; ... procedure Test; const cFirmen: TArray<String> = ['Firma1', 'Firma2', 'Firma3']; cNamen: TArray<String> = ['Name1', 'Name2', 'Name3']; cPersonList = '[{"name":"Name1"},{"name":"Name2"},{"name":"Name3"}]'; cFirmaList = '[{"name":"Firma1","personList":' + cPersonList + '},' + '{"name":"Firma2","personList":' + cPersonList + '},' + '{"name":"Firma3","personList":' + cPersonList + '}]'; cWrapperJSON = '{"list":' + cFirmaList + '}'; function CheckList(AListe: TPersonList): Boolean; overload; var I: Integer; begin Result := (AListe.Count = Length(cNamen)); if Result then begin for I := 0 to AListe.Count - 1 do if AListe[I].Name <> cNamen[I] then Exit(False); end; end; function CheckList(AListe: TFirmaList): Boolean; overload; var I: Integer; begin Result := (AListe.Count = Length(cFirmen)); if Result then begin for I := 0 to AListe.Count - 1 do begin if AListe[I].Name <> cFirmen[I] then Exit(False); if not CheckList(AListe[I].PersonList) then Exit(False); end; end; end; procedure FillList(Target: TPersonList); overload; begin for var lName in cNamen do begin var lPerson := TPerson.Create; lPerson.Name := lName; Target.Add(lPerson); end; end; procedure FillList(Target: TFirmaList); overload; begin for var lName in cFirmen do begin var lFirma := TFirma.Create; lFirma.Name := lName; FillList(lFirma.PersonList); Target.Add(lFirma); end; end; var lFirma: TFirma; lWrapper: TWrapper; lJSONString: String; lFirmaList: TFirmaList; begin { mit Wrapper } lWrapper := TWrapper.Create; try FillList(lWrapper.List); lJSONString := TConvert.ToJSONString(lWrapper); Assert(lJSONString = cWrapperJSON); finally lWrapper.Free; end; lWrapper := TConvert.FromJSON<TWrapper>(cWrapperJSON); try Assert(CheckList(lWrapper.List)); finally lWrapper.Free; end; { Liste direkt } lFirmaList := TFirmaList.Create; try FillList(lFirmaList); lJSONString := TConvert.ToJSONString(lFirmaList); Assert(lJSONString = cFirmaList); finally lFirmaList.Free; end; lFirmaList := TFirmaList.Create; try lFirmaList.AddRange(TConvert.FromJSONArray<TFirma>(cFirmaList)); Assert(CheckList(lFirmaList)); finally lFirmaList.Free; end; end; |
AW: ObjectList serialisieren JSON
Tut mir leid, mein Fehler.
Hatte in TFirma FPersonList nicht erzeugt. Vielen Dank für die Hilfe :thumb: |
AW: ObjectList serialisieren JSON
|
AW: ObjectList serialisieren JSON
Liste der Anhänge anzeigen (Anzahl: 1)
Ich häng mich mal hier an.
Ich versuche seit geraumer Zeit meine Settings mit Hilfe von Uwe Raabes unit Rest.Json.Helpers in Json zu serialsieren. Viellicht habe ich etwas falsch verstanden. Im Anhang ist ein abgespecktes Beispiel. Das TConvert.ToJSONString funktioniert. Rückwärts aber weder mit TConvert.FromJSON noch mit der Delphi Funktion TJson.JsonToObject. Irgendwann erhalte ich eine Zugriffsverletzung in System.Generics.Collections in der procedure TListHelper.InternalSetCount4(Value: Integer); Projekt ist erstellt mit Delphi 10.4.2 Was mache ich falsch? |
AW: ObjectList serialisieren JSON
Mit Debug-DCU kompiliert, siehst du schnell, dass es eigentlich in REST.Json.Helpers.TObjectListInterceptor<T>.Object sReverter knallt.
Wenn man sich die Zeile
Delphi-Quellcode:
zum Debuggen etwas aufdröselt, dann erhalten wir so ein Konstrukt:
list := TObjectList<T>(ctx.GetType(Data.ClassType).GetField(Field).GetValue(Data).AsObject);
Delphi-Quellcode:
Dadurch bekommst du zumindest die Information, dass der Cast von TValue.AsObject nach der TObjectList<T> (im konkreten Fall TIOList = TObjectList<TIODevice>) fehlschlägt und nil zurückliefert.
procedure TObjectListInterceptor<T>.ObjectsReverter(Data: TObject; Field: string; Args: TListOfObjects);
var ctx: TRTTIContext; list: TObjectList<T>; obj: TObject; RttiType: TRttiType; RttiField: TRttiField; RttiValue: TValue; ListObj: TObject; begin RttiType := ctx.GetType(Data.ClassType); RttiField := RttiType.GetField(Field); RttiValue := RttiField.GetValue(Data); ListObj := RttiValue.AsObject; list := TObjectList<T>(ListObj); if list <> nil then begin list.Clear; for obj in Args do list.Add(T(obj)); end; end; In
Delphi-Quellcode:
sieht man, dass Result = nil ist, weil TValue.GetIsEmpty True zurückgibt.
TValue.AsObject
Das liegt daran, weil FAsObject = nil ist. Warum und Wieso entzieht sich meinen Verständnis. Beim füllen des TValue per
Delphi-Quellcode:
bleibt die TValue.FValueData leer.
RttiField.GetValue(Data) und TValue.Make
|
AW: ObjectList serialisieren JSON
Zitat:
![]() |
AW: ObjectList serialisieren JSON
Zitat:
Code:
[dcc32 Warnung] uSettings.pas(33): W1074 Unbekanntes benutzerdefiniertes Attribut
[dcc32 Warnung] uSettings.pas(71): W1074 Unbekanntes benutzerdefiniertes Attribut [dcc32 Warnung] uSettings.pas(74): W1074 Unbekanntes benutzerdefiniertes Attribut |
AW: ObjectList serialisieren JSON
Zitat:
|
AW: ObjectList serialisieren JSON
TGate hat keinen parameterloses Constructor Create. Deshalb wird das TObject.Create verwendet (das gibt es immer) und somit ist FCameras nicht initialisiert.
Das intern verwendete TJSONUnmarshal erzeugt die Instanzen mit Hilfe der Funktion ObjectInstance. Dort steht als Bemerkung: Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:53 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