Flutter中multipart请求如何发送Map对象而非字符串类型值
问题原因
http.MultipartRequest的fields属性设计上仅支持Map<String, String>类型的键值对,原生不支持直接传入嵌套Map结构,你当前遇到的经纬度参数为空问题是因为BarberAddress类未实现toJson方法,导致json.encode无法正确序列化对象字段。
可行解决方案
方案1:后端配合解析JSON字符串(改动最小)
这是最常用的处理方式,仅需前端补全模型类的序列化方法,后端拿到字段后做一次JSON反序列化即可得到完整嵌套结构,直接存入MongoDB:
- 先给
BarberAddress类补全toJson方法:
class BarberAddress { BarberAddress({ @required this.state, @required this.city, @required this.street, this.location, }); String state; String city; String street; BarberLocation location; // 新增toJson方法 Map<String, dynamic> toJson() => { "State": state, "City": city, "Street": street, "location": location?.toJson(), }; factory BarberAddress.fromJson(Map<String, dynamic> json) => BarberAddress( state: json["State"], city: json["City"], street: json["Street"], location: BarberLocation.fromJson(json["location"]), ); }
- 你原有请求代码无需修改,
json.encode(barberAddress)就会生成正确的嵌套JSON字符串,后端拿到barberAddress字段值后反序列化即可得到结构化Map。
方案2:展平嵌套字段(无需后端额外解析)
如果后端希望直接接收结构化的FormData参数,不需要做JSON反序列化,可以将嵌套Map展平为带点分隔的键名传入,绝大多数服务端框架会自动将这类键组装为嵌套对象:
postFormDataBarber({ @required String endPoint, File picB,barberName,BarberAddress barberAddress, }) async { var url = Uri.parse('${BaseUrl.baseUrl}$endPoint'); var request = http.MultipartRequest("POST", url); // 展平barberAddress字段 request.fields["barberAddress.State"] = barberAddress.state; request.fields["barberAddress.City"] = barberAddress.city; request.fields["barberAddress.Street"] = barberAddress.street; request.fields["barberAddress.location.lat"] = barberAddress.location.lat.toString(); request.fields["barberAddress.location.lang"] = barberAddress.location.lang.toString(); request.files.add(picB); final data = await request.send(); return data; }
内容的提问来源于stack exchange,提问作者Iman Kamali
相关产品推荐
相关产品推荐

