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是数组。
需要做以下修改:
- 将整个请求体转换为JSON字符串,而非用
Map作为body - 给请求头添加
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
相关产品推荐
相关产品推荐

