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

Flutter向Post API发送嵌套数组数据报错,求正确实现方式

问题:Post API请求中medicines数组格式报错怎么解决?

问题背景

我需要调用一个Post API,要求发送的请求体格式如下:

{
    "pharmacy_id" : 15,
    "medicines": [{"medicine_id": 500, "amount": 2},{"medicine_id": 520, "amount": 5}],
    "latitude" : 24.2594,
    "longitude" : 27.654
}

我构造的medicines是List<Map<String,dynamic>>类型,生成的数据为:

[{"medicine_id": 500, "amount": 2},{"medicine_id": 520, "amount": 5}]

但后端返回报错:

{"message":"The given data was invalid.","errors":{"medicines":["The medicines must be an array."]}}

状态码为422(Unprocessable Content)。

我的代码

API请求函数

Future<void> cartOrder({required String pharmacy_id,required int pharmID, required List<Map<String,dynamic>> medicines, String? coupon, required BuildContext context}) async{
    emit(HomeGetAboutUsLoadingState());
    await http.post(
        Uri.parse('${api}order/store'),
        body:{
          'pharmacy_id': pharmacy_id,
          'medicines': medicines,
          'latitude': latitude,
          'longitude': longitude,
          'coupon': coupon
        }, headers: {'Accept': 'application/json', 'Authorization' : 'Bearer ${CacheHelper.getData(key: 'token')}'
    }).then((value){
      oneOrderModel = OneOrderModel.fromJson(jsonDecode(value.body));
      print("value body is : ${value.body}");
      print("oneOrderModel is $oneOrderModel");
      print("value.reasonPhrase is : ${value.reasonPhrase}");
      print("value.statusCode is : ${value.statusCode}");
      print("cartOrder value is : $value");
      navigateFinalTo(context,const HomeDrawer());
      print("cart order value is : $value");
      print("cart order success");
      Fluttertoast.showToast(msg: "تم إرسال طلبك بنجاح");
      print("load user order");
      UserOrders();
      print("user order loaded");
      int index = 0;
      myItems.forEach((element) {
        deleteRowCart(id: pharmID, index: index);
        index++;
      });
      print("my list item is empty now");
      emit(HomeGetAboutUsSuccessState());
    }).catchError((error){
      print("cart order error is : $error");
      emit(HomeGetAboutUsErrorState());
    });
  }

medicines列表构造代码

var extractMap = cubit.myItems.map((element) => Map.fromEntries([
MapEntry('medicine_id', element['medicineID']),
MapEntry('amount', element['quantity']),])).toList();
print("my order items is : $extractMap");
extractMap.isNotEmpty ?
cubit.cartOrder(context: context,
pharmID: cubit.onePharmacyModel!.data!.id!.toInt(),
pharmacy_id: cubit.onePharmacyModel!.data!.id!.toString(),
medicines: extractMap,
coupon: codeController.text.toString()
): Fluttertoast.showToast(msg: "cart is empty");

解决方案

问题根源在于:直接将List<Map>放入body时,http.post默认会把Map编码成x-www-form-urlencoded格式,这种格式无法正确传递嵌套数组结构,导致后端识别不到medicines是数组。

需要做以下修改:

  1. 将整个请求体转换为JSON字符串,而非用Map作为body
  2. 给请求头添加Content-Type: application/json,明确告知后端请求体格式

修改后的API请求函数:

Future<void> cartOrder({required String pharmacy_id,required int pharmID, required List<Map<String,dynamic>> medicines, String? coupon, required BuildContext context}) async{
    emit(HomeGetAboutUsLoadingState());
    // 构造完整请求体Map
    final requestBody = {
      'pharmacy_id': pharmacy_id,
      'medicines': medicines,
      'latitude': latitude,
      'longitude': longitude,
      'coupon': coupon
    };
    await http.post(
        Uri.parse('${api}order/store'),
        // 将请求体序列化为JSON字符串
        body: jsonEncode(requestBody),
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json', // 新增该请求头
          'Authorization' : 'Bearer ${CacheHelper.getData(key: 'token')}'
        }
    ).then((value){
      // 后续逻辑保持不变
      oneOrderModel = OneOrderModel.fromJson(jsonDecode(value.body));
      print("value body is : ${value.body}");
      print("oneOrderModel is $oneOrderModel");
      print("value.reasonPhrase is : ${value.reasonPhrase}");
      print("value.statusCode is : ${value.statusCode}");
      print("cartOrder value is : $value");
      navigateFinalTo(context,const HomeDrawer());
      print("cart order value is : $value");
      print("cart order success");
      Fluttertoast.showToast(msg: "تم إرسال طلبك بنجاح");
      print("load user order");
      UserOrders();
      print("user order loaded");
      int index = 0;
      myItems.forEach((element) {
        deleteRowCart(id: pharmID, index: index);
        index++;
      });
      print("my list item is empty now");
      emit(HomeGetAboutUsSuccessState());
    }).catchError((error){
      print("cart order error is : $error");
      emit(HomeGetAboutUsErrorState());
    });
  }

关键说明

  • jsonEncode(requestBody)会把整个请求体转为标准JSON字符串,确保嵌套数组结构被正确传递
  • Content-Type: application/json头是REST API传递复杂数据的标准配置,让后端能正确解析JSON格式的请求体
  • x-www-form-urlencoded格式仅适合传递简单键值对,不支持复杂嵌套结构

内容的提问来源于stack exchange,提问作者Saayeed M Daawoud

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 21:54:36