英文:
Nested values in url.Values
问题
我正在开发一个API客户端,需要能够使用client.PostForm请求发送一个嵌套的JSON结构。我遇到的问题是:
reqBody := url.Values{
"method": {"server-method"},
"arguments": {
"download-dir": {"/path/to/downloads/dir"},
"filename": {variableWithURL},
"paused": {"false"},
},
}
当我尝试go build
时,出现以下错误:
./transmission.go:17: syntax error: unexpected :, expecting }
./transmission.go:24: non-declaration statement outside function body
./transmission.go:26: non-declaration statement outside function body
./transmission.go:27: non-declaration statement outside function body
./transmission.go:29: non-declaration statement outside function body
./transmission.go:38: non-declaration statement outside function body
./transmission.go:39: syntax error: unexpected }
我想知道在这种情况下创建嵌套值的正确方法是什么。提前感谢!
英文:
I'm working on an API client and I need to be able to send a nested JSON structure with a client.PostForm request. The issue I'm encountering is this:
reqBody := url.Values{
"method": {"server-method"},
"arguments": {
"download-dir": {"/path/to/downloads/dir"},
"filename": {variableWithURL},
"paused": {"false"},
},
}
When I try to go build
this, I get the following errors:
./transmission.go:17: syntax error: unexpected :, expecting }
./transmission.go:24: non-declaration statement outside function body
./transmission.go:26: non-declaration statement outside function body
./transmission.go:27: non-declaration statement outside function body
./transmission.go:29: non-declaration statement outside function body
./transmission.go:38: non-declaration statement outside function body
./transmission.go:39: syntax error: unexpected }
I'm wondering what the correct way to created a nested set of values in this scenario. Thanks in advance!
答案1
得分: 3
你没有正确使用url.Values
,根据源代码(url包,url.go):
// Values将字符串键映射到值列表。
// 它通常用于查询参数和表单值。
// 与http.Header映射中的键不同,
// Values映射中的键区分大小写。
type Values map[string][]string
但是arguments
不符合这个定义,因为arguments
的对象不是一个字符串数组。
英文:
You are not using properly the url.Values
, according to the source code (url package, url.go):
// Values maps a string key to a list of values.
// It is typically used for query parameters and form values.
// Unlike in the http.Header map, the keys in a Values map
// are case-sensitive.
type Values map[string][]string
But arguments
is not compliant with the definition because the object of arguments
is not an array of strings.
答案2
得分: 3
我能自己解决这个问题!答案是将所有东西都结构化!
type Command struct {
Method string `json:"method,omitempty"`
Arguments Arguments `json:"arguments,omitempty"`
}
type Arguments struct {
DownloadDir string `json:"download-dir,omitempty"`
Filename string `json:"filename,omitempty"`
Paused bool `json:"paused,omitempty"`
}
然后,在创建你的 PostForm 时:
jsonBody, err := json.Marshal(reqBody) // reqBody 是一个 Command
if err != nil {
return false
}
req, err := http.NewRequest("POST", c.Url, strings.NewReader(string(jsonBody)))
希望这能帮到你!
英文:
I was able to figure this out on my own! The answer is to struct all-the-things!
type Command struct {
Method string `json:"method,omitempty"`
Arguments Arguments `json:"arguments,omitempty"`
}
type Arguments struct {
DownloadDir string `json:"download-dir,omitempty"`
Filename string `json:"filename,omitempty"`
Paused bool `json:"paused,omitempty"`
}
Then, when creating your PostForm:
jsonBody, err := json.Marshal(reqBody) // reqBody is a Command
if (err != nil) {
return false
}
req, err := http.NewRequest("POST", c.Url, strings.NewReader(string(jsonBody)))
Hope this helps!
答案3
得分: 0
我在Connor的答案中使用了NewRequest
,但是使用struct
然后进行编组对我来说似乎是一个不必要的步骤。
我直接将嵌套的JSON字符串传递给了strings.NewReader
:
import (
"net/http"
"strings"
)
reqBody := strings.NewReader(`{
"method": {"server-method"},
"arguments": {
"download-dir": {"/path/to/downloads/dir"},
"paused": {"false"},
},
}`)
req, err := http.NewRequest("POST", "https://httpbin.org/post", reqBody)
希望对那些被Go的http.PostForm
困扰的人有所帮助,因为它只接受url.Values
作为参数,而url.Values
无法生成嵌套的JSON。
英文:
I used NewRequest
as Connor mentions in his answer but using a struct
and then marshalling it seems an unnecessary step to me.
I passed my nested json string straight to strings.NewReader
:
import (
"net/http"
"strings"
)
reqBody := strings.NewReader(`{
"method": {"server-method"},
"arguments": {
"download-dir": {"/path/to/downloads/dir"},
"paused": {"false"},
},
}`)
req, err := http.NewRequest("POST", "https://httpbin.org/post", reqBody)
Hope it helps those who are stuck with Go's http PostForm which only accepts url.Values
as argument while url.Values
cannot generate nested json.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论