Flutter使用Dio提交含数组POST请求时出现500错误求助
Flutter Dio POST请求返回500错误修复方案
问题概述
使用Dio 5.1.2(含旧版本)提交包含items数组的POST请求时,返回DioError [bad response]: The request returned an invalid status code of 500错误,但相同请求在Postman中可正常运行。
Postman请求格式参考:
核心问题分析
1. 请求参数传递方式错误
现有代码将POST请求体参数放在queryParameters中,而Dio中queryParameters用于URL查询参数,POST请求的请求体应使用data参数传递,导致后端无法正确解析请求体。
2. 手动构建参数时的序列化错误
手动构建data时,对items数组的每个元素执行了jsonEncode,导致数组元素是JSON字符串而非对象,后端解析失败。
3. Model序列化逻辑错误
EditedStockDataModel.fromJson中错误遍历json['services']而非json['items'],与实际请求字段不符;toJson中错误将items赋值给data['services'],且未正确将items列表序列化为JSON对象数组;type字段映射错误,实际请求中对应for字段。
修复方案
方案1:修复手动参数构建与请求调用
修复后的请求代码
Dio() .post('${Urls.baseUrl}/vendor/v1/stores/updateItemByGroup', options: Options( headers: { "Accept": "application/json", "Authorization": "Bearer $token" }, ), data: data) // 将queryParameters替换为data
修复后的参数构建逻辑
var data = { "store_id": widget.storeId.toString(), "for": "stock", "same_amount": 'false' }; for (int i = 0; i < widget.items.data!.length; i++) { data.addAll({ "items[$i]": ref .watch(editStocksProvider.notifier) .state[i] // 移除jsonEncode,直接传入对象 }); }
方案2:修复Model序列化逻辑并使用Model发送请求
修复后的Model代码
class EditedStockDataModel { String? storeId; List<EditedStockModel>? items; String? type; String? sameAmount; EditedStockDataModel({this.type, this.sameAmount, this.storeId, this.items}); EditedStockDataModel.fromJson(Map<String, dynamic> json) { storeId = json['store_id']; if (json['items'] != null) { items = <EditedStockModel>[]; json['items'].forEach((v) { // 修正为遍历items字段 items!.add(EditedStockModel.fromJson(v)); }); } type = json['for']; // 修正字段映射,type对应请求中的for sameAmount = json['same_amount']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data['store_id'] = this.storeId; data['for'] = this.type; data['same_amount'] = this.sameAmount; if (this.items != null) { data['items'] = this.items!.map((v) => v.toJson()).toList(); // 修正为将items序列化为对象数组 } return data; } } class EditedStockModel { int? id; String? stock; String? maxPerOrder; EditedStockModel({this.id, this.stock, this.maxPerOrder}); EditedStockModel.fromJson(Map<String, dynamic> json) { id = json['id']; stock = json['stock']; maxPerOrder = json['max_per_order']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data['id'] = this.id; data['stock'] = this.stock; data['max_per_order'] = this.maxPerOrder; return data; } }
使用Model发送请求的代码
// 构建Model实例 var stockDataModel = EditedStockDataModel( storeId: widget.storeId.toString(), type: "stock", sameAmount: "false", items: ref.watch(editStocksProvider.notifier).state.map((item) => EditedStockModel( id: item.id, stock: item.stock, maxPerOrder: item.maxPerOrder, )).toList(), ); // 发送请求 Dio() .post('${Urls.baseUrl}/vendor/v1/stores/updateItemByGroup', options: Options( headers: { "Accept": "application/json", "Authorization": "Bearer $token" }, ), data: stockDataModel.toJson())
额外排查建议
添加Dio日志拦截器,查看实际发送的请求体与Postman对比,确认参数格式是否一致:
Dio dio = Dio(); // 添加日志拦截器,打印请求和响应详情 dio.interceptors.add(LogInterceptor(requestBody: true, responseBody: true));
内容的提问来源于stack exchange,提问作者dinomim
相关产品推荐
相关产品推荐

