Is there a way to get TJson.ObjectToJsonString() properly serialize a TNullableInteger field in an object?
I tried to use an attribute on the field using a JsonReflectAttribute with a TJSONInterceptor, but then the integer value, if present, was serialized as string.
JSON serialization that comes with Delphi is a disaster - as already mentioned in the comment to your question the design of REST.Json prevents any customization of record serializion from what I can see.
The only way known to me is to use a TJsonSerializer from System.JSON.Serializers and add a custom converter that can handle Nullable<T> quite easily:
uses
Spring,
System.JSON.Serializers,
System.JSON.Readers,
System.JSON.Writers,
System.Rtti;
type
TNullableConverter = class(TJsonConverter)
public
function CanConvert(ATypeInf: PTypeInfo): Boolean; override;
function ReadJson(const AReader: TJsonReader; ATypeInf: PTypeInfo;
const AExistingValue: TValue; const ASerializer: TJsonSerializer): TValue; override;
procedure WriteJson(const AWriter: TJsonWriter; const AValue: TValue;
const ASerializer: TJsonSerializer); override;
end;
function TNullableConverter.CanConvert(ATypeInf: PTypeInfo): Boolean;
begin
Result := IsNullable(ATypeInf);
end;
function TNullableConverter.ReadJson(const AReader: TJsonReader;
ATypeInf: PTypeInfo; const AExistingValue: TValue;
const ASerializer: TJsonSerializer): TValue;
begin
Result := AExistingValue;
Result.SetNullableValue(AReader.Value.Convert(GetUnderlyingType(ATypeInf), ISO8601FormatSettings));
end;
procedure TNullableConverter.WriteJson(const AWriter: TJsonWriter;
const AValue: TValue; const ASerializer: TJsonSerializer);
var
LTypeInfo: PTypeInfo;
LValue: TValue;
begin
LTypeInfo := GetUnderlyingType(AValue.TypeInfo);
LValue := AValue.GetNullableValue;
if LValue.IsEmpty then
AWriter.WriteNull
else
if (LTypeInfo = TypeInfo(TDate)) or (LTypeInfo = TypeInfo(TTime)) then
AWriter.WriteValue(LValue.Convert<string>(ISO8601FormatSettings))
else
AWriter.WriteValue(LValue);
end;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With