delphi Spring4D Nullable < T>JSON序列化

v6ylcynt  于 2023-10-18  发布在  Spring
关注(0)|答案(1)|浏览(147)

有没有办法让TJson.ObjectToJsonString()正确序列化对象中的TNullableInteger字段?
我尝试使用TJSONInterceptorJsonReflectAttribute在字段上使用属性,但是整数值(如果存在)被序列化为字符串。

7bsow1i6

7bsow1i61#

Delphi 自带的JSON序列化是一场灾难--正如在对你的问题的评论中已经提到的,从我所看到的来看,REST.Json的设计阻止了任何记录序列化的定制。
我所知道的唯一方法是使用System.JSON.Serializers中的TJsonSerializer,并添加一个可以轻松处理Nullable<T>的自定义转换器:

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;

相关问题