mirror of https://github.com/gin-gonic/gin.git
feat(context): add BindQuery func (#1029)
* feat(context): add BindQuery func, only parse/bind the query string params. * docs(readme): add BindQuery section. * docs(readme): fix import. * docs(readme): separate import
This commit is contained in:
parent
74221b8a35
commit
c19aa0598b
38
README.md
38
README.md
|
@ -460,7 +460,43 @@ func main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Bind Query String
|
### Only Bind Query String
|
||||||
|
|
||||||
|
`BindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
Name string `form:"name"`
|
||||||
|
Address string `form:"address"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
route := gin.Default()
|
||||||
|
route.Any("/testing", startPage)
|
||||||
|
route.Run(":8085")
|
||||||
|
}
|
||||||
|
|
||||||
|
func startPage(c *gin.Context) {
|
||||||
|
var person Person
|
||||||
|
if c.BindQuery(&person) == nil {
|
||||||
|
log.Println("====== Only Bind By Query String ======")
|
||||||
|
log.Println(person.Name)
|
||||||
|
log.Println(person.Address)
|
||||||
|
}
|
||||||
|
c.String(200, "Success")
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bind Query String or Post Data
|
||||||
|
|
||||||
See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
|
See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ var (
|
||||||
JSON = jsonBinding{}
|
JSON = jsonBinding{}
|
||||||
XML = xmlBinding{}
|
XML = xmlBinding{}
|
||||||
Form = formBinding{}
|
Form = formBinding{}
|
||||||
|
Query = queryBinding{}
|
||||||
FormPost = formPostBinding{}
|
FormPost = formPostBinding{}
|
||||||
FormMultipart = formMultipartBinding{}
|
FormMultipart = formMultipartBinding{}
|
||||||
ProtoBuf = protobufBinding{}
|
ProtoBuf = protobufBinding{}
|
||||||
|
|
|
@ -67,6 +67,18 @@ func TestBindingForm2(t *testing.T) {
|
||||||
"", "")
|
"", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBindingQuery(t *testing.T) {
|
||||||
|
testQueryBinding(t, "POST",
|
||||||
|
"/?foo=bar&bar=foo", "/",
|
||||||
|
"foo=unused", "bar2=foo")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBindingQuery2(t *testing.T) {
|
||||||
|
testQueryBinding(t, "GET",
|
||||||
|
"/?foo=bar&bar=foo", "/?bar2=foo",
|
||||||
|
"foo=unused", "")
|
||||||
|
}
|
||||||
|
|
||||||
func TestBindingXML(t *testing.T) {
|
func TestBindingXML(t *testing.T) {
|
||||||
testBodyBinding(t,
|
testBodyBinding(t,
|
||||||
XML, "xml",
|
XML, "xml",
|
||||||
|
@ -204,6 +216,21 @@ func testFormBinding(t *testing.T, method, path, badPath, body, badBody string)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testQueryBinding(t *testing.T, method, path, badPath, body, badBody string) {
|
||||||
|
b := Query
|
||||||
|
assert.Equal(t, b.Name(), "query")
|
||||||
|
|
||||||
|
obj := FooBarStruct{}
|
||||||
|
req := requestWithBody(method, path, body)
|
||||||
|
if method == "POST" {
|
||||||
|
req.Header.Add("Content-Type", MIMEPOSTForm)
|
||||||
|
}
|
||||||
|
err := b.Bind(req, &obj)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, obj.Foo, "bar")
|
||||||
|
assert.Equal(t, obj.Bar, "foo")
|
||||||
|
}
|
||||||
|
|
||||||
func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
func testBodyBinding(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
||||||
assert.Equal(t, b.Name(), name)
|
assert.Equal(t, b.Name(), name)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright 2017 Manu Martinez-Almeida. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package binding
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type queryBinding struct{}
|
||||||
|
|
||||||
|
func (queryBinding) Name() string {
|
||||||
|
return "query"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (queryBinding) Bind(req *http.Request, obj interface{}) error {
|
||||||
|
values := req.URL.Query()
|
||||||
|
if err := mapForm(obj, values); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return validate(obj)
|
||||||
|
}
|
|
@ -467,6 +467,11 @@ func (c *Context) BindJSON(obj interface{}) error {
|
||||||
return c.MustBindWith(obj, binding.JSON)
|
return c.MustBindWith(obj, binding.JSON)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BindQuery is a shortcut for c.MustBindWith(obj, binding.Query)
|
||||||
|
func (c *Context) BindQuery(obj interface{}) error {
|
||||||
|
return c.MustBindWith(obj, binding.Query)
|
||||||
|
}
|
||||||
|
|
||||||
// MustBindWith binds the passed struct pointer using the specified binding
|
// MustBindWith binds the passed struct pointer using the specified binding
|
||||||
// engine. It will abort the request with HTTP 400 if any error ocurrs.
|
// engine. It will abort the request with HTTP 400 if any error ocurrs.
|
||||||
// See the binding package.
|
// See the binding package.
|
||||||
|
|
|
@ -1186,6 +1186,22 @@ func TestContextBindWithJSON(t *testing.T) {
|
||||||
assert.Equal(t, w.Body.Len(), 0)
|
assert.Equal(t, w.Body.Len(), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContextBindWithQuery(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 `form:"foo"`
|
||||||
|
Bar string `form:"bar"`
|
||||||
|
}
|
||||||
|
assert.NoError(t, c.BindQuery(&obj))
|
||||||
|
assert.Equal(t, "foo", obj.Bar)
|
||||||
|
assert.Equal(t, "bar", obj.Foo)
|
||||||
|
assert.Equal(t, 0, w.Body.Len())
|
||||||
|
}
|
||||||
|
|
||||||
func TestContextBadAutoBind(t *testing.T) {
|
func TestContextBadAutoBind(t *testing.T) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
|
Loading…
Reference in New Issue