Flutter使用Provider调用Chopper提交POST请求时出现DateTime编码错误
错误根因
提交的Map<String, dynamic>请求参数中包含DateTime类型对象,Dart标准JSON序列化工具默认仅支持数字、字符串、布尔值、数组、普通Map、空值这几类基础类型,无法直接序列化DateTime对象,因此抛出转换失败异常。
GET请求可正常运行是因为仅涉及服务端返回JSON字符串转Dart对象的反序列化流程,你项目中已经对DateTime反序列化做了适配,而POST请求需要将Dart对象转成JSON字符串,缺少对应的序列化适配逻辑。
解决方案
方案1:接口调用前手动转换DateTime字段
在调用postPersonal方法前,遍历data Map把所有DateTime类型的值转换成服务端可识别的格式,比如ISO8601字符串或毫秒级时间戳:
onPressed: () async { final form = _formKey.currentState; if (form!.validate()) { form.save(); showNotification(); // 新增DateTime转换逻辑 final processedData = data.map((key, value) { if (value is DateTime) { // 服务端要求时间戳就替换为 value.millisecondsSinceEpoch return MapEntry(key, value.toIso8601String()); } return MapEntry(key, value); }); await Provider.of<PersonalPostingService>(context, listen: false) .postPersonal(processedData); } }
方案2:自定义Chopper转换器全局适配
如果项目多接口都需要传输DateTime参数,可重写Chopper的JsonConverter,统一处理DateTime序列化逻辑:
class CustomJsonConverter extends JsonConverter { @override Object? encodeJson(dynamic data) { // 处理DateTime类型序列化 if (data is DateTime) { return data.toIso8601String(); } // 递归处理嵌套Map里的DateTime if (data is Map<String, dynamic>) { return data.map((key, value) => MapEntry(key, encodeJson(value))); } // 递归处理数组里的DateTime if (data is List) { return data.map((item) => encodeJson(item)).toList(); } return super.encodeJson(data); } }
完成后在初始化ChopperClient时,将原本的JsonConverter替换为自定义的CustomJsonConverter即可全局生效。
内容的提问来源于stack exchange,提问作者artistAhmed
相关产品推荐
相关产品推荐

