You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TJSONUnMarshal如何为JSONObject子项注册Reverter?

解决TJSONUnMarshal嵌套对象Reverter不触发的问题

核心结论:完全可以给JSONObject子项设置Reverter,你的问题是Reverter的注册方式不对,没关联到嵌套对象的反序列化流程里。

问题原因

单独反序列化TCustomerHeader时,TJSONUnMarshal直接识别到目标类型是TCustomerHeader,会触发你注册的对应Reverter;但反序列化顶层的TCustomer时,默认只会扫描针对TCustomer类型注册的Reverter,不会自动关联子类型的Reverter——除非你明确给子类型或者子字段路径注册。

两种可行的解决方法

1. 全局注册子类型TCustomerHeader的Reverter

这种方式不管是嵌套还是单独反序列化TCustomerHeader,都会触发Reverter,通用性强:

// 注册TCustomerHeader类型的changeDate字段Reverter
JSONUnMarshal.RegisterReverter(TypeInfo(TCustomerHeader), 'changeDate',
  procedure(Obj: TObject; const Value: TJSONValue)
  var
    Header: TCustomerHeader;
    DateStr: string;
  begin
    Header := TCustomerHeader(Obj);
    if Value is TJSONString then
    begin
      DateStr := TJSONString(Value).Value;
      // 替换成你的实际日期解析逻辑,比如处理自定义格式
      Header.changeDate := StrToDate(DateStr);
    end;
  end);

注意:注册时要指定子类型TCustomerHeader的TypeInfo,而不是顶层的TCustomer。

2. 针对顶层对象的子字段路径注册Reverter

如果只需要处理TCustomer里的header子对象的changeDate,可以直接指定字段路径,精准控制:

// 针对TCustomer的header.changeDate字段注册Reverter
JSONUnMarshal.RegisterReverter(TypeInfo(TCustomer), 'header.changeDate',
  procedure(Obj: TObject; const Value: TJSONValue)
  var
    Customer: TCustomer;
    DateStr: string;
  begin
    Customer := TCustomer(Obj);
    if Value is TJSONString then
    begin
      DateStr := TJSONString(Value).Value;
      Customer.header.changeDate := StrToDate(DateStr);
    end;
  end);

额外注意事项

  • 确认JSON字段名和Delphi类属性名完全匹配(如果JSON里是changedate而类里是changeDate,需要用[JSONName('changedate')]标注属性)
  • Reverter必须在反序列化操作之前注册,否则不会生效
  • 如果日期格式是非标准格式,要在Reverter里用自定义解析逻辑(比如TryStrToDate加格式参数,或者用TDateTimeHelper的Parse方法)

内容的提问来源于stack exchange,提问作者MonkeySleeve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 20:57:28