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
相关产品推荐
相关产品推荐

