【问题标题】:Echo Framework Bind() html FormDataEcho 框架 Bind() html FormData
【发布时间】:2019-06-21 11:01:59
【问题描述】:

我有一个类似的 HTML 表单:

<input name="email"type="email" />
<input name="password"type="password" />
<input name="tags[name][]"type="text" />
<input name="tags[count][]"type="number" />
<input name="tags[name][]"type="text" />
<input name="tags[count][]"type="number" />
<input name="tags[name][]"type="text" />
<input name="tags[count][]"type="number" />
<input name="freeword[]"type="text" />
<input name="freeword[]"type="text" />

我想Bind()这个表格和我的struct一样:

type UserFrom struct {
  Email string `json:"email" form:"email" query:"email"`
  Password string `json:"password" form:"password" query:"password"`
  Tags []Tag
  Free []string `json:"freeword[]" form:"freeword[]" query:"freeword[]"`
}
type Tag struct {
  Name string `json:"tags[name][]" form:"tags[name][]" query:"tags[name][]"`
  Count string `json:"tags[count][]" form:"tags[count][]" query:"tags[count][]"`
}

但如果我在POST 之后打印Bind() 的结果,我有:

u := new(UserFrom)
if err = c.Bind(u); err != nil {
  return
}
log.Println(u)

这个糟糕的输出:

&{email@mail.tld pwdpwdpwd [] [word1 word2]}

UserFrom 结构中的行 Tags []Tag 不起作用

如果你尝试将 Tags []Tag 更改为 Tags Tag 我有一个很好的最后一个条目

&{email@mail.tld pwdpwdpwd {tag3 3} [word1 word2]}

我想要这个输出:

&{email@mail.tld pwdpwdpwd [{tag1 1} {tag2 2} {tag3 3}] [word1 word2]}

你知道这个问题吗?

Echo Doc to Bind()

【问题讨论】:

    标签: go


    【解决方案1】:

    有两个问题:

    1. 您没有正确指定表单输入名称,您拥有它们的方式永远无法映射到您想要的任何语言。在支持您想要的语言中,它将标签映射到两个字段(名称和计数)的结构,每个字段都由一个数组组成。不是名称和计数的结构数组。名称应该像这样tags[][name] 以实现您想要的,例如:HTML Form: POST an array of objects
    2. 即使您按照上述方法正确指定了名称,它也无法在 Echo 中工作,因为它依赖于 http.Request.Form 来解析值,这实际上是 url.Values,而这又只是 map[string][]string。如您所见,这不可能捕获您想要的结构。这是一张相关的票:https://github.com/golang/go/issues/29703

    现在,仅仅因为 Echo 不支持开箱即用,并不意味着您不能这样做。您可以使用具有您需要的功能的第三方库进行绑定,例如https://github.com/monoculum/formam

    以下代码:

    package main
    
    import (
        "fmt"
        "net/url"
    
        "github.com/monoculum/formam"
    )
    
    type User struct {
        Email,
        Password string
        Tags []struct {
            Tag   string
            Count int
        }
    }
    
    func main() {
        formData := "Email=joe@example.com&Password=secret&Tags[0].Tag=red&" + 
            "Tags[0].Count=1&Tags[1].Tag=blue"
        q, _ := url.ParseQuery(formData)
        u := new(User)
    
        dec := formam.NewDecoder(nil)
        if err := dec.Decode(q, u); err != nil {
            fmt.Println(err)
            return
        }
    
        fmt.Println(u)
    }
    

    满足您的需求:

    &{joe@example.com secret [{red 1} {blue 0}]}
    

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 1970-01-01
      相关资源
      最近更新 更多