Hallo zusammen,
ich bin gerade über einen Fall gestolpert, wo ein REST-WebService unbedingt leere Arrays als
codiert haben möchte.
Der Serialisierer aus REST.Json.TJson macht mir aber daraus immer
.
Soll das so? Erlaubt der JSON-Standard beide Varianten?
Kann ich das beeinflussen? Die optionalen TJsonOptions haben mich nicht weitergebracht.
Gibt es noch eine einfache Möglichkeit außer sich das JSON per Hand zurecht zu friemeln?
Nicht falsch verstehen, ein StringReplace um null mit [] zu ersetzen ist jetzt nicht das Drama, aber ich wundere mich schon.
Delphi ist Berlin 10.2!
Zum drübergucken:
Delphi-Quellcode:
program JSONDeserialisationProblem;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
REST.Json,
System.JSON,
DefinitionUnit
in '
DefinitionUnit.pas';
procedure Main;
var
MyItems: TArrayOfDataItem;
Response1: IResponse;
Response2: IResponse;
I: Integer;
JsonObject: TJSONObject;
ObjectAsJSONString,
ObjectAsJSONString2,
ObjectAsJSONString3,
ObjectAsJSONString4:
string;
Count: Integer;
begin
Response1 := TResponse.Create;
Count := 0;
//Length(MyItems) + 3;
SetLength(MyItems, Count);
for I := low(MyItems)
to high(MyItems)
do
begin
MyItems[I] := TDataItem.Create;
MyItems[I].Data := I;
end;
Response1.Items := MyItems;
JsonObject := TJson.ObjectToJsonObject(Response1
as TResponse);
ObjectAsJSONString := TJson.Format(JsonObject);
ObjectAsJSONString2 := JsonObject.ToString;
ObjectAsJSONString3 := JsonObject.ToJSON;
ObjectAsJSONString4 := TJson.JsonEncode(JsonObject);
Writeln(ObjectAsJSONString);
Writeln(ObjectAsJSONString2);
Writeln(ObjectAsJSONString3);
Writeln(ObjectAsJSONString4);
Response2 := TJson.JsonToObject<TResponse>(ObjectAsJSONString);
end;
begin
ReportMemoryLeaksOnShutdown := True;
try
Main;
Readln;
except
on E:
Exception do
Writeln(E.ClassName, '
: ', E.
Message);
end;
end.
Delphi-Quellcode:
unit DefinitionUnit;
interface
type
IDataItem =
interface;
TArrayOfDataItem =
array of IDataItem;
IDataItem =
interface
['
{C0AB4BD7-3C7B-4E79-949F-5DCEB7A560F9}']
function GetData: Int64;
stdcall;
procedure SetData(
const Value: Int64);
stdcall;
property Data: Int64
read GetData
write SetData;
end;
TDataItem =
class(TInterfacedObject, IDataItem)
private
FData: Int64;
function GetData: Int64;
stdcall;
procedure SetData(
const Value: Int64);
stdcall;
public
property Data: Int64
read GetData
write SetData;
end;
IResponse =
interface
['
{691AD522-27B9-4F20-95ED-C192D73D6EE2}']
function GetItems: TArrayOfDataItem;
stdcall;
procedure SetItems(
const Value: TArrayOfDataItem);
stdcall;
property Items: TArrayOfDataItem
read GetItems
write SetItems;
end;
TResponse =
class(TInterfacedObject, IResponse)
private
FDataItems: TArray<TDataItem>;
// TArrayOfDataItem;
function GetItems: TArrayOfDataItem;
stdcall;
procedure SetItems(
const Value: TArrayOfDataItem);
stdcall;
public
property Items: TArrayOfDataItem
read GetItems
write SetItems;
end;
implementation
{ TDataItem }
function TDataItem.GetData: Int64;
begin
Result := FData;
end;
procedure TDataItem.SetData(
const Value: Int64);
begin
FData := Value;
end;
{ TResponse }
function TResponse.GetItems: TArrayOfDataItem;
var
I: Integer;
begin
SetLength(Result, Length(FDataItems));
for I := Low(FDataItems)
to High(FDataItems)
do
begin
Result[I] := FDataItems[I]
as IDataItem;
end;
end;
procedure TResponse.SetItems(
const Value: TArrayOfDataItem);
var
I: Integer;
begin
SetLength(FDataItems, Length(Value));
for I := Low(FDataItems)
to High(FDataItems)
do
begin
FDataItems[I] := Value[I]
as TDataItem;
end;
end;
end.
Zum Runterladen: