使用Flutter Chopper与Provider提交数据到服务端时出现DateTime编码错误
异常原因
该异常和Provider的使用无关,是Chopper做请求JSON序列化时触发的错误:Dart 内置的JSON序列化器默认仅支持 num、String、bool、List、Map、null 这几类基础类型,你提交的_user.dataMap集合中包含了DateTime类型的字段,序列化器无法直接将DateTime实例转换为可传输的JSON格式,因此抛出该错误。
修复方案
有两种常用的修复方式:
- 方案1:提交前手动处理DateTime字段
提交请求前先遍历处理Map中的DateTime字段,将其转换为ISO8601格式字符串或者时间戳:onPressed: () async { final form = _formKey.currentState; if (form!.validate()) { form.save(); showNotification(); // 处理数据中的DateTime字段 Map<String, dynamic> processedData = Map.from(_user.data); processedData.forEach((key, value) { if (value is DateTime) { // 转ISO格式字符串,也可以替换为millisecondsSinceEpoch转时间戳 processedData[key] = value.toIso8601String(); } }); await Provider.of<PersonalPostingService>( context, listen: false) .postPersonal(processedData); } }, - 方案2:自定义Chopper全局JSON转换器
如果项目中大量接口都需要传递DateTime类型参数,可以重写Chopper的JsonConverter,实现全局自动处理DateTime序列化:
初始化ChopperClient时,将原来的JsonConverter替换为自定义的CustomJsonConverter即可。class CustomJsonConverter extends JsonConverter { @override dynamic encodeJson(dynamic data) { // 处理Map中的DateTime if (data is Map) { data.forEach((key, value) { if (value is DateTime) { data[key] = value.toIso8601String(); } else if (value is Map || value is List) { encodeJson(value); } }); } // 处理List中的DateTime else if (data is List) { for (int i = 0; i < data.length; i++) { var item = data[i]; if (item is DateTime) { data[i] = item.toIso8601String(); } else if (item is Map || item is List) { encodeJson(item); } } } return super.encodeJson(data); } }
内容的提问来源于stack exchange,提问作者artistAhmed
相关产品推荐
相关产品推荐

