我需要将一个Object作为body参数发送到Post请求。我的对象是从嵌套的Json创建的,到目前为止我无法使它工作。
我在JavaScript中很容易做到这一点,但我还没有找到在Dart / Flutter中做到这一点的方法。
我以前做过的“常规”方式很简单:
var data = {
"email": "[email protected]",
"password": "123",
"first_name": "qweqwe",
"billing": {
"email": "[email protected]",
"phone": "321654978",
},
"shipping": {
"first_name": "qweqwe",
}
}
通过在Dart / Flutter中使用相同的结构,我得到以下错误
[错误:flutter / lib / ui / ui_dart_state.cc(148)]未处理的异常:类型'_InternalLinkedHashMap'不是类型转换中类型'String'的子类型
我试过Map<String, dynamic>
,Map<String, String>
,使用我的数据模型....
如果我发送相同的Json,但没有"billing"
和"shipping"
(没有嵌套的Json),它的工作原理。
在JSON中,只应在值之间使用逗号。
var data = {
"email": "[email protected]",
"password": "123",
"first_name": "qweqwe",
"billing": {
"email": "[email protected]",
"phone": "321654978"
},
"shipping": {
"first_name": "qweqwe"
}
}
在这里,我删除了“phone”和“first_name”字段末尾的逗号。
如果你想上传你的data
对象的排序答案是将它转换为如下字符串:
var jsonString = json.encode(data);
// upload jsonString as body to your server.
print("Json String is " + jsonString);
Map headers = {
'Content-type' : 'application/json',
};
http.post("www.server.com/myPostEndpoint", body: jsonString, headers: headers);
就像在评论中讨论的那样,您可能需要将整个内容包装在data
属性中。你可以试试这个:
var payload = {
"data": {
"email": "[email protected]",
"password": "123",
"first_name": "qweqwe",
"billing": {
"email": "[email protected]",
"phone": "321654978",
},
"shipping": {
"first_name": "qweqwe",
}
}
};
var jsonString = json.encode(payload); // upload jsonString as body to your server. print("Json String is " + jsonString);
Map headers = { 'Content-type': 'application/json', };
http.post("www.server.com/myPostEndpoint", body: jsonString, headers: headers);
tl;博士
创建模型总是一个好主意。所以这可能是你的User
模型:
class User {
final String email;
final String password;
final String firstName;
final Map<String, String> billing;
final Map<String, String> shipping;
User({this.email, this.password, this.firstName, this.billing, this.shipping});
static User fromJson(dynamic json) {
return User(
email: json["email"],
password: json["password"],
firstName: json["first_name"],
billing: json["billing"],
shipping: json["shipping"],
);
}
}
它有一个静态构造函数,可以方便地从一段解码的json中创建这个User
的实例。
现在您可以继续在代码中使用此模型,如下所示:
var data = {
"email": "[email protected]",
"password": "123",
"first_name": "qweqwe",
"billing": {
"email": "[email protected]",
"phone": "321654978",
},
"shipping": {
"first_name": "qweqwe",
}
};
var user = User.fromJson(data);
print("Users Email is ${user.billing["email"]}");
为Billing
和Shipping
创建模型甚至更清晰。
这是一个完整的示例,其中还包括从解析模型生成Json的toJson()
方法:
class User {
final String email;
final String password;
final String firstName;
final Billing billing;
final Shipping shipping;
User({this.email, this.password, this.firstName, this.billing, this.shipping});
static User fromJson(dynamic json) {
return User(
email: json["email"],
password: json["password"],
firstName: json["first_name"],
billing: Billing.fromJson(json["billing"]),
shipping: Shipping.fromJson(json["shipping"]),
);
}
Map<String, dynamic> toJson() => {'email': email, 'password': password, 'first_name': firstName, 'billing': billing.toJson(), 'shipping': shipping.toJson()};
}
class Billing {
final String email;
final String phone;
Billing({this.email, this.phone});
static Billing fromJson(dynamic json) {
return Billing(email: json["email"], phone: json["phone"]);
}
Map<String, dynamic> toJson() => {'email': email, 'phone': phone};
}
class Shipping {
final String name;
Shipping({
this.name,
});
static Shipping fromJson(dynamic json) {
return Shipping(
name: json["first_name"],
);
}
Map<String, dynamic> toJson() => {'name': name};
}
这就是你如何使用它:
var data = {
"email": "[email protected]",
"password": "123",
"first_name": "qweqwe",
"billing": {
"email": "[email protected]",
"phone": "321654978",
},
"shipping": {
"first_name": "qweqwe",
}
};
var user = User.fromJson(data);
print("Users Email is ${user.billing.email}");
print("Shipping name is ${user.shipping.name}");
var jsonString = json.encode(user.toJson()); // upload this as body to your server.
print("Json String is " + jsonString);
我认为其他答案可能(非常)过于复杂。无论您使用哪种语言,要将JSON发送到服务器,您都需要将数据作为字符串发送,并使用application/json
内容类型。 json.encode
已经处理嵌套地图,因此您不需要做任何特别的事情......根本不需要:
// Replace the "..." with the rest of your data.
var data = {"email": "[email protected]", "password": "123", ...}
// `asJson` is a String.
var asJson = json.encode(data);
// Send it
var response = await client.post('example.com/...', body: asJson, headers: {'content-type', 'application/json'});
这就是你需要做的。没有必要用User
,fromJson
等制作一个完整的toJson
课程。
至于这个错误 - Unhandled Exception: type '_InternalLinkedHashMap' is not a subtype of type 'String' in type cast
,我不知道究竟是什么原因,因为你没有提供相关的代码,但很明显,在某些时候,你给Dart一个Map,它期待一个String。就像你说的,你已经尝试过Map<String, dynamic>
和Map<String, String
,但真正需要的是String
。
如果你还没有使用Dart分析器(通常在IDE插件中),这就是它可以轻易捕获的错误。
希望这有帮助!
TLDR:调用json.encode(data)
获取String
,然后将String
以及application/json
内容类型发送到服务器。