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

Dart使用json_serializable嵌套对象反序列化类型转换报错

问题根因

报错核心是json_serializable默认配置下,不会自动递归调用嵌套自定义类型的toJson方法。你当前生成的_$OfficesListToJson方法直接将List<Office>类型的offices字段塞入返回结果,导致list1.toJson()输出的结构中,offices字段存储的是Office实例列表,而非序列化后的Map<String, dynamic>列表,反序列化执行e as Map<String, dynamic>强转时就会抛出类型不匹配异常。

修复方案

两种方案选其一即可,修复后重新执行代码生成命令dart run build_runner build --delete-conflicting-outputs(Flutter项目替换为flutter pub run build_runner build --delete-conflicting-outputs)即可正常运行。

  • 全局配置(推荐,一劳永逸):在项目根目录新建/修改build.yaml文件,添加如下配置,全局开启嵌套对象自动序列化:
targets:
  $default:
    builders:
      json_serializable:
        options:
          explicit_to_json: true
  • 单类配置:如果不需要全局生效,直接在需要嵌套序列化的类上的@JsonSerializable注解中开启参数即可:
@JsonSerializable(explicitToJson: true)
class OfficesList {
  List<Office> offices;
  OfficesList({required this.offices});

  factory OfficesList.fromJson(Map<String, dynamic> json) => _$OfficesListFromJson(json);

  Map<String, dynamic> toJson() => _$OfficesListToJson(this);
}

配置生效后重新生成的toJson方法会自动补全嵌套对象的序列化逻辑,生成代码如下:

Map<String, dynamic> _$OfficesListToJson(OfficesList instance) =>
    <String, dynamic>{
      'offices': instance.offices.map((e) => e.toJson()).toList(),
    };
json_serializable 自动生成代码适配规则
  • 默认行为:explicitToJson默认值为false,生成toJson时不会递归处理嵌套的自定义类型,直接返回原对象实例,该设计是为了避免无意义的深层序列化带来的性能损耗。
  • 嵌套序列化触发条件:只要给类设置explicitToJson: true,生成代码时就会递归扫描所有字段,对拥有toJson方法的自定义类型自动调用对应序列化逻辑,支持任意层级的对象嵌套。
  • 反序列化逻辑默认支持嵌套:你当前生成的fromJson方法已经正确实现了嵌套类型的转换逻辑,只要toJson输出的结构符合Map嵌套的标准JSON结构,反序列化就不会抛出类型错误。
  • 你的测试代码逻辑本身没有问题,修复配置重新生成代码后即可正常运行,输出正确的序列化结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 12:36:27