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

Flutter+Freezed处理JSON多类型ID转Int时Build Runner报错

解决Freezed模型中ID字段多类型解析的空值错误问题

错误原因分析

出现“Null check operator used on a null value”的核心原因是:自定义转换器未处理ID字段为null的场景,或者在转换逻辑中使用了!强制解包空值。比如数据库返回的ID是null,但转换器直接尝试对null执行类型转换或强制解包,就会触发该错误。

解决方案

方案1:修复自定义JsonConverter

调整转换器逻辑,兼容null、int、string三种场景,同时用安全解析避免崩溃:

class IntFromStringConverter implements JsonConverter<int?, dynamic> {
  const IntFromStringConverter();

  @override
  int? fromJson(dynamic json) {
    if (json == null) return null; // 明确处理null情况
    if (json is int) return json;
    if (json is String) return int.tryParse(json); // 用tryParse避免非数字字符串崩溃
    return null; // 其他未知类型返回null或按需处理
  }

  @override
  dynamic toJson(int? value) => value; // 序列化时直接返回int类型
}

在Freezed模型中使用转换器:

@freezed
class User with _$User {
  const factory User({
    @IntFromStringConverter() int? id,
    String? name,
  }) = _User;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}

方案2:直接在fromJson方法中自定义解析

如果不想用转换器,可直接在模型的fromJson里手动处理ID字段,灵活性更高:

@freezed
class User with _$User {
  const factory User({
    int? id,
    String? name,
  }) = _User;

  factory User.fromJson(Map<String, dynamic> json) {
    // 手动解析ID字段
    dynamic idRaw = json['id'];
    int? parsedId;
    if (idRaw != null) {
      if (idRaw is int) {
        parsedId = idRaw;
      } else if (idRaw is String) {
        parsedId = int.tryParse(idRaw);
      }
    }
    // 替换处理后的ID,再调用生成的解析方法
    return _$UserFromJson({
      ...json,
      'id': parsedId,
    });
  }
}

注意事项

  • 避免随意使用!强制解包,必须处理null场景
  • 若字符串ID可能包含非数字内容,int.tryParse比int.parse更安全,不会直接崩溃
  • 构建前可先执行dart run build_runner clean清理旧生成文件,再运行dart run build_runner build

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:02:33