解析带有绑定的数组表单元素

huangapple go评论79阅读模式
英文:

Parsing array form elements with bindings

问题

我正在尝试在Go中提交和解析一个表单,但无法正确解析表单字段。以下是我尝试的代码摘录。

formtest.go:

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/codegangsta/negroni"
	"github.com/davecgh/go-spew/spew"
	"github.com/julienschmidt/httprouter"
	"github.com/mholt/binding"
	"gopkg.in/unrolled/render.v1"
)

type FormInfo struct {
	Fields    []string
	Action    string
	PageTitle string
	Id        string
}

func (f *FormInfo) FieldMap(*http.Request) binding.FieldMap {
	return binding.FieldMap{
		&f.Fields: "fields",
		&f.Action: "action",
	}
}

func formtest(
	resp http.ResponseWriter,
	req *http.Request,
	p httprouter.Params) {

	info := new(FormInfo)
	tkt := p.ByName("tkt")
	info.PageTitle = tkt
	info.Id = tkt

	if req.Method == "POST" {
		bind_err := binding.Bind(req, info)
		if bind_err.Handle(resp) {
			log.Println("Error decoding form contents")
			return
		}
		spew.Dump(info)
	}

	Render.HTML(resp, http.StatusOK, "formtest", info)
	return
}

var Render *render.Render

func main() {

	router := httprouter.New()

	router.GET("/formtest", formtest)
	router.POST("/formtest", formtest)

	Render = render.New(render.Options{
		Layout:          "layout",
		IndentJSON:      true,
		IndentXML:       true,
		HTMLContentType: "text/html",
		IsDevelopment:   true,
	})

	n := negroni.New(
		negroni.NewRecovery(),
		negroni.NewLogger(),
		negroni.NewStatic(http.Dir("static")),
	)
	n.UseHandler(router)
	n.Run(fmt.Sprintf(":%d", 3000))

}

templates/layout.tmpl:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>{{ .PageTitle }}</title>
    <meta http-equiv="Content-Type" content="text/html;" charset="utf-8">
	<meta charset="UTF-8">
    <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
    <link rel="apple-touch-icon" href="/mobile.png" />
	<meta name="viewport" 
          content="initial-scale=1.0,width=device-width,user-scalable=no">
	<meta name="generator" content="Go">
	<link rel="stylesheet" href="/base.css" type="text/css">
  </head>

  <body>

      <div class="mainbody">
        {{ yield }}
      </div>

  </body>

</html>

templates/formtest.tmpl:

<h1>{{ .PageTitle }}</h1>

<form action="/formtest/{{ .Id }}" method="POST">

    <div class="details">
      <label>Question 1</label>
      <input type="text" name="fields[0]" value="value 1" />
    </div>

    <div class="details">
      <label>Question 2</label>
      <input type="text" name="fields[1]" value="value 2" />
    </div>

    <div class="details">
      <input type="submit" name="action" value="save" />
    </div>

</form>

步骤:

  1. 运行 go run formtest.go
  2. 打开浏览器,访问 http://127.0.0.1:3000/formtest
  3. 提交表单
  4. 检查控制台日志。

观察结果:

(*main.FormInfo)(0xc820066c30)({
Fields: ([]string) <nil>,
Action: (string) (len=4) "save",
PageTitle: (string) "",
Id: (string) ""
})

期望结果:

Fields: ([]string) <包含两个提交值>,

但是当我尝试打印 Fields 的内容时,它是 nil。我做错了什么?

英文:

I am trying to submit and parse a form in go and I am failing to parse the form fields properly.
Here is an excerpt of the code I am trying.

formtest.go :
package main

import (
&quot;fmt&quot;
&quot;log&quot;
&quot;net/http&quot;
&quot;github.com/codegangsta/negroni&quot;
&quot;github.com/davecgh/go-spew/spew&quot;
&quot;github.com/julienschmidt/httprouter&quot;
&quot;github.com/mholt/binding&quot;
&quot;gopkg.in/unrolled/render.v1&quot;
)
type FormInfo struct {
Fields    []string
Action    string
PageTitle string
Id        string
}
func (f *FormInfo) FieldMap(*http.Request) binding.FieldMap {
return binding.FieldMap{
&amp;f.Fields: &quot;fields&quot;,
&amp;f.Action: &quot;action&quot;,
}
}
func formtest(
resp http.ResponseWriter,
req *http.Request,
p httprouter.Params) {
// var ticket Ticket
info := new(FormInfo)
tkt := p.ByName(&quot;tkt&quot;)
info.PageTitle = tkt
info.Id = tkt
if req.Method == &quot;POST&quot; {
bind_err := binding.Bind(req, info)
if bind_err.Handle(resp) {
log.Println(&quot;Error decoding form contents&quot;)
return
}
spew.Dump(info)
}
Render.HTML(resp, http.StatusOK, &quot;formtest&quot;, info)
return
}
var Render *render.Render
func main() {
router := httprouter.New()
router.GET(&quot;/formtest&quot;, formtest)
router.POST(&quot;/formtest&quot;, formtest)
Render = render.New(render.Options{
Layout:          &quot;layout&quot;,
IndentJSON:      true,
IndentXML:       true,
HTMLContentType: &quot;text/html&quot;,
IsDevelopment:   true,
})
n := negroni.New(
negroni.NewRecovery(),
negroni.NewLogger(),
negroni.NewStatic(http.Dir(&quot;static&quot;)),
)
n.UseHandler(router)
n.Run(fmt.Sprintf(&quot;:%d&quot;, 3000))
}

templates/layout.tmpl :

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;title&gt;{{ .PageTitle }}&lt;/title&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html;&quot; charset=&quot;utf-8&quot;&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;link rel=&quot;shortcut icon&quot; type=&quot;image/x-icon&quot; href=&quot;/favicon.ico&quot; /&gt;
&lt;link rel=&quot;apple-touch-icon&quot; href=&quot;/mobile.png&quot; /&gt;
&lt;meta name=&quot;viewport&quot; 
content=&quot;initial-scale=1.0,width=device-width,user-scalable=no&quot;&gt;
&lt;meta name=&quot;generator&quot; content=&quot;Go&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;/base.css&quot; type=&quot;text/css&quot;&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;mainbody&quot;&gt;
{{ yield }}
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;

templates/formtest.tmpl :

&lt;h1&gt;{{ .PageTitle }}&lt;/h1&gt;
&lt;form action=&quot;/formtest/{{ .Id }}&quot; method=&quot;POST&quot;&gt;
&lt;div class=&quot;details&quot;&gt;
&lt;label&gt;Question 1&lt;/label&gt;
&lt;input type=&quot;text&quot; name=&quot;fields[0]&quot; value=&quot;value 1&quot; /&gt;
&lt;/div&gt;
&lt;div class=&quot;details&quot;&gt;
&lt;label&gt;Question 2&lt;/label&gt;
&lt;input type=&quot;text&quot; name=&quot;fields[1]&quot; value=&quot;value 2&quot; /&gt;
&lt;/div&gt;
&lt;div class=&quot;details&quot;&gt;
&lt;input type=&quot;submit&quot; name=&quot;action&quot; value=&quot;save&quot; /&gt;
&lt;/div&gt;
&lt;/form&gt;

Procedure:

  1. go run formtest.go
  2. Open browser and go to http://127.0.0.1:3000/formtest
  3. Submit the form
  4. Check console for the logs.

Observation :

(*main.FormInfo)(0xc820066c30)({
Fields: ([]string) &lt;nil&gt;,
Action: (string) (len=4) &quot;save&quot;,
PageTitle: (string) &quot;&quot;,
Id: (string) &quot;&quot;
})

Expectation :

Fields: ([]string) &lt;contains two values submitted&gt;,

But when I try to print the contents of Fields, it is nil.
What am I doing wrong?

答案1

得分: 1

绑定不起作用。您表单的字段 - name = "fields [1]" 和 name = "fields [0]" 是相互独立的,因此对于每个字段,您的结构应包含自己的字段:

type FormInfo struct {
Fields1 string
Fields2 string
Action string
PageTitle string
Id string
}

在处理程序中分别为它们赋值:

...
&f.Fields1: "fields[0]",
&f.Fields2: "fields[1]",
&f.Action: "action",
...

结果将是:

(*main.FormInfo)(0xc08200aa50)({
Fields1: (string) (len=7) "value 1",
Fields2: (string) (len=7) "value 2",
Action: (string) (len=4) "save",
PageTitle: (string) "",
Id: (string) ""
})
编辑:

如果您更改表单中的代码:

...
<input type="text" name="fields"...
<input type="text" name="fields"...

您可以获得:

info.Fields = [value 1 value 2]

而无需更改其原始代码。

英文:

Binding so not work. The fields of your form - name = "fields [1]" and
name = "fields [0]" are independent from each other, so for each of them your structure should contain its own field:

type FormInfo struct {
Fields1   string
Fields2   string
Action    string
PageTitle string
Id        string
}

respectively, in the handler:

...
&amp;f.Fields1: &quot;fields[0]&quot;,
&amp;f.Fields2: &quot;fields[1]&quot;,
&amp;f.Action:  &quot;action&quot;,
...

As a result, the output will be:

(*main.FormInfo)(0xc08200aa50)({
Fields1: (string) (len=7) &quot;value 1&quot;,
Fields2: (string) (len=7) &quot;value 2&quot;,
Action: (string) (len=4) &quot;save&quot;,
PageTitle: (string) &quot;&quot;,
Id: (string) &quot;&quot;
})

EDIT:

If you change the code in the form on the

...
&lt;input type=&quot;text&quot; name=&quot;fields&quot;...
&lt;input type=&quot;text&quot; name=&quot;fields&quot;...

you can get

info.Fields = [value 1 value 2]

without changing its original code.

huangapple
  • 本文由 发表于 2015年9月28日 12:09:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/32815561.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定