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

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请求格式参考:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 04:30:11