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

Flutter使用json_serializable转模型时嵌套可选对象缺失字段报错如何解决

问题根源

你仅将User类的city属性声明为可空,不影响City类本身的解析逻辑。City类中的name是不可空String类型,当JSON的city对象缺失name字段时,json_serializable在解析City实例的阶段就会抛出类型不匹配异常,还未到给User的city属性赋值的环节,因此外层可空声明不会生效。

解决方案

方案1:为嵌套字段自定义带容错的解析逻辑(推荐)

直接在User类的city字段上通过@JsonKey注解指定自定义解析方法,捕获City解析过程中的异常,解析失败直接返回null:

@JsonSerializable()
class User {
    int id;
    String name;

    // 新增注解,指定自定义解析方法
    @JsonKey(fromJson: _nullableCityFromJson)
    City? city;

    // 其余代码不变,fromJson、toJson方法正常生成
    factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
    Map<String, dynamic> toJson() => _$UserToJson(this);
}

// 顶层的自定义解析方法,需和User类在同一个文件中
City? _nullableCityFromJson(Map<String, dynamic>? json) {
  if (json == null) return null;
  try {
    return City.fromJson(json);
  } catch (_) {
    // 解析失败(缺必填字段、字段类型不匹配等)直接返回null
    return null;
  }
}

这种方案无需修改原有City类的定义,侵入性最低,同时能精准控制单字段的容错逻辑。

方案2:修改City类字段为可空,主动校验必填字段

如果你的业务允许City类字段可空,可以修改City定义,新增安全解析方法,校验必填字段完整才返回实例,否则返回null:

@JsonSerializable()
class City {
  int? id;
  String? name;

  factory City.fromJson(Map<String, dynamic> json) => _$CityFromJson(json);
  Map<String, dynamic> toJson() => _$CityToJson(this);

  // 自定义安全构造方法
  static City? fromJsonSafe(Map<String, dynamic>? json) {
    if (json == null) return null;
    final city = City.fromJson(json);
    // 校验你认为的必填字段,任意缺失就返回null
    if (city.id == null || city.name == null) return null;
    return city;
  }
}

// User类的city字段绑定该安全方法即可
@JsonKey(fromJson: City.fromJsonSafe)
City? city;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 20:24:05