我正在尝试通过以下方式发送JSON put body请求。当我手动输入JSON作为字符串时,它可以工作,但是当我尝试通过代码创建JSON时,它失败:
struct Item: Codable {
let name: String
let price: Float
}
struct User: Codable {
let username: String
let fullName: String
}
let item = Item(name: "pen", price: 0)
let itemData = try! JSONEncoder().encode(item)
let itemString = String(data: itemData, encoding: .utf8)!
let user = User(username: "Dave", fullName: "Dave Grohl")
let userData = try! JSONEncoder().encode(user)
let userString = String(data: userData, encoding: .utf8)!
let parametersJson: [String: Any] = [
"item": itemString,
"user": userString
]
Alamofire请求如下:
AF.request("http://127.0.0.1:8000/items/10",
method: .put,
parameters: parametersJson,
encoding: JSONEncoding.default)
.response { (response) in
debugPrint(response)
我得到的回应:
[Response Body]:
{"detail":[{"loc":["body","item"],"msg":"value is not a valid dict","type":"type_error.dict"},{"loc":["body","user"],"msg":"value is not a valid dict","type":"type_error.dict"}]}
同时,当我使用以下参数时,它可以正常工作:
let parameters: [String: [String:String]] = [
"item": [
"name": "pen",
"price": "0"
],
"user": [
"username": "dave",
"full_name": "Dave Grohl"
]
非常感谢您的帮助。
#根据科学怪人的评论,我已经更改了User结构,以更正fullName和full_name之间的不匹配,但仍然会收到相同的错误。当我调试打印请求时,得到以下信息:
[Request Body]:
{"user":"{\"username\":\"Dave\",\"full_name\":\"Dave Grohl\"}","item":"{\"name\":\"pen\",\"price\":0}"}
这就是使用参数(如上定义为字符串)时得到的:
[Request Body]:
{"item":{"name":"pen","price":"0"},"user":{"username":"dave","full_name":"Dave Grohl"}}
更新:这里的主要问题是您没有正确格式化JSON
,这是您需要做的事情:
struct Item: Codable {
let name: String
let price: Float
}
struct User: Codable {
let username: String
let fullName: String
enum CodingKeys: String, CodingKey {
case username
case fullName = "full_name"
}
}
struct Parameter: Codable {
let user: User
let item: Item
}
let item = Item(name: "pen", price: 0)
let user = User(username: "Dave", fullName: "Dave Grohl")
let parameter = Parameter(user: user, item: item)
let data = try! JSONEncoder().encode(parameter)
var request = URLRequest(url: url)
request.httpMethod = "PUT"
request.httpBody = data
AF.request(request).response { (response) in
debugPrint(response)
//...
}
上一个答案:这是因为您的参数在User
中不匹配。您可以通过如下修改User
结构来修复它:
struct User: Codable {
let username: String
let fullName: String
enum CodingKeys: String, CodingKey {
case username
case fullName = "full_name"
}
}
另一种方法是使用自定义JSONDecoder
并将其从keyEncodingStrategy
设置为convertToSnakeCase
,如下所示:
let user = User(username: "Dave", fullName: "Dave Grohl")
let decoder = JSONEncoder()
decoder.keyEncodingStrategy = .convertToSnakeCase
let userData = try! decoder.encode(user)
let userString = String(data: userData, encoding: .utf8)!
注意:通常JSON
格式同时包含蛇形和驼峰形,因此我认为使用第一种方法是更好的选择。但是两者都可以。