binding: add ShouldBindQuery2 and BindQuery2

```go
ackage main

import (
	"github.com/gin-gonic/gin"
)

type testQuery struct {
	Size int    `query:"size"`
	Page int    `query:"page"`
	Ak   string `query:"ak"`
}

func main() {
	g := gin.Default()

	g.GET("/query", func(c *gin.Context) {
		q := testQuery{}
		err := c.ShouldBindQuery2(&q)
		if err != nil {
			return
		}
		c.JSON(200, q)
	})

	g.Run()
}

// curl '127.0.0.1:8080/query?size=10&page=20&ak=test'
```
This commit is contained in:
guonaihong 2019-10-14 22:04:27 +08:00
parent f7becac7bc
commit 48e871a76d
4 changed files with 62 additions and 0 deletions

View File

@ -72,6 +72,7 @@ var (
XML = xmlBinding{}
Form = formBinding{}
Query = queryBinding{}
Query2 = queryBinding2{}
FormPost = formPostBinding{}
FormMultipart = formMultipartBinding{}
ProtoBuf = protobufBinding{}

View File

@ -19,3 +19,18 @@ func (queryBinding) Bind(req *http.Request, obj interface{}) error {
}
return validate(obj)
}
// Support for query tag binding data
type queryBinding2 struct{}
func (queryBinding2) Name() string {
return "query"
}
func (queryBinding2) Bind(req *http.Request, obj interface{}) error {
if err := mapFormByTag(obj, req.URL.Query(), "query"); err != nil {
return err
}
return validate(obj)
}

View File

@ -572,6 +572,11 @@ func (c *Context) BindQuery(obj interface{}) error {
return c.MustBindWith(obj, binding.Query)
}
// BindQuery2 is a shortcut for c.MustBindWith(obj, binding.Query2).
func (c *Context) BindQuery2(obj interface{}) error {
return c.MustBindWith(obj, binding.Query2)
}
// BindYAML is a shortcut for c.MustBindWith(obj, binding.YAML).
func (c *Context) BindYAML(obj interface{}) error {
return c.MustBindWith(obj, binding.YAML)
@ -631,6 +636,11 @@ func (c *Context) ShouldBindQuery(obj interface{}) error {
return c.ShouldBindWith(obj, binding.Query)
}
// ShouldBindQuery2 is a shortcut for c.ShouldBindWith(obj, binding.Query2).
func (c *Context) ShouldBindQuery2(obj interface{}) error {
return c.ShouldBindWith(obj, binding.Query2)
}
// ShouldBindYAML is a shortcut for c.ShouldBindWith(obj, binding.YAML).
func (c *Context) ShouldBindYAML(obj interface{}) error {
return c.ShouldBindWith(obj, binding.YAML)

View File

@ -1474,6 +1474,22 @@ func TestContextBindWithQuery(t *testing.T) {
assert.Equal(t, 0, w.Body.Len())
}
func TestContextBindWithQuery2(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest("POST", "/?foo=bar&bar=foo", bytes.NewBufferString("foo=unused"))
var obj struct {
Foo string `query:"foo"`
Bar string `query:"bar"`
}
assert.NoError(t, c.BindQuery2(&obj))
assert.Equal(t, "foo", obj.Bar)
assert.Equal(t, "bar", obj.Foo)
assert.Equal(t, 0, w.Body.Len())
}
func TestContextBindWithYAML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
@ -1607,6 +1623,26 @@ func TestContextShouldBindWithQuery(t *testing.T) {
assert.Equal(t, 0, w.Body.Len())
}
func TestContextShouldBindWithQuery2(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)
c.Request, _ = http.NewRequest("POST", "/?foo=bar&bar=foo&Foo=bar1&Bar=foo1", bytes.NewBufferString("foo=unused"))
var obj struct {
Foo string `query:"foo"`
Bar string `query:"bar"`
Foo1 string `query:"Foo"`
Bar1 string `query:"Bar"`
}
assert.NoError(t, c.ShouldBindQuery2(&obj))
assert.Equal(t, "foo", obj.Bar)
assert.Equal(t, "bar", obj.Foo)
assert.Equal(t, "foo1", obj.Bar1)
assert.Equal(t, "bar1", obj.Foo1)
assert.Equal(t, 0, w.Body.Len())
}
func TestContextShouldBindWithYAML(t *testing.T) {
w := httptest.NewRecorder()
c, _ := CreateTestContext(w)