diff --git a/README.md b/README.md
index ef801179..ac724b43 100644
--- a/README.md
+++ b/README.md
@@ -47,6 +47,8 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi
- [Bind Query String or Post Data](#bind-query-string-or-post-data)
- [Bind Uri](#bind-uri)
- [Bind Header](#bind-header)
+ - [Bind Cookie](#bind-cookie)
+ - [Bind Request](#bind-request)
- [Bind HTML checkboxes](#bind-html-checkboxes)
- [Multipart/Urlencoded binding](#multiparturlencoded-binding)
- [XML, JSON, YAML and ProtoBuf rendering](#xml-json-yaml-and-protobuf-rendering)
@@ -663,10 +665,10 @@ Note that you need to set the corresponding binding tag on all fields you want t
Also, Gin provides two sets of methods for binding:
- **Type** - Must bind
- - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`, `BindHeader`
+ - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`, `BindHeader`, `BindCookie`, `BindRequest`
- **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
- **Type** - Should bind
- - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`, `ShouldBindHeader`
+ - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`, `ShouldBindHeader`, `ShouldBindCookie`, `ShouldBindReqeust`
- **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
@@ -991,6 +993,79 @@ func main() {
// output
// {"Domain":"music","Rate":300}
}
+```
+### Bind Cookie
+
+see [Bind Request](#bind-request)
+
+
+### Bind Request
+
+`c.BindRequest` and `c.ShouldBindRquest` can bind all wanted values into struct instance at once.
+Now,
++ supports values from `form`, `uri`, `header`, `cookie`
+and request `req.Body`.
++ `req.Body` decocder is decided by header `Content-Type` value, see more [request_test.go](./binding/binding_request_test.go#L40)
+
+**example**
+
+```go
+package main
+
+import (
+ "net/http"
+ "github.com/gin-gonic/gin"
+)
+
+type Params struct {
+ Name string `uri:"name"`
+ Age int `form:"age,default=18"`
+ Money int32 `form:"money" binding:"required"`
+ Authorization string `cookie:"Authorization"`
+ UserAgent string `header:"User-Agent"`
+ Data *ParamBody `body:"body" mime:"json"`
+}
+
+type ParamBody struct {
+ Replicas *int32 `json:"replicas"`
+}
+
+func NewParams() *Params {
+ return &Params{
+ Data: &ParamBody{},
+ }
+}
+
+func main() {
+ r := gin.Default()
+
+ r.POST("/hello/:name", handler)
+ _ = r.Run(":9881")
+
+}
+
+func handler(c *gin.Context) {
+ var err error
+ params := NewParams()
+
+ err = c.ShouldBindRequest(params)
+ if err != nil {
+ c.JSON(http.StatusBadRequest, err)
+ return
+ }
+
+ c.JSON(200, params)
+}
+
+// ### POST test by RestClient of vscode extenstion
+// POST http://127.0.0.1:9881/hello/zhangsan?money=1000
+// Content-Type: application/json
+// Accept-Language: en-GB,en-US;q=0.8,en;q=0.6,zh-CN;q=0.4
+//
+// {
+// "replicas":5
+// }
+
```
### Bind HTML checkboxes
diff --git a/binding/binding.go b/binding/binding.go
index deb71661..3eb32943 100644
--- a/binding/binding.go
+++ b/binding/binding.go
@@ -30,6 +30,7 @@ const (
type Binding interface {
Name() string
Bind(*http.Request, interface{}) error
+ BindOnly(*http.Request, interface{}) error
}
// BindingBody adds BindBody method to Binding. BindBody is similar with Bind,
@@ -37,6 +38,7 @@ type Binding interface {
type BindingBody interface {
Binding
BindBody([]byte, interface{}) error
+ BindBodyOnly([]byte, interface{}) error
}
// BindingUri adds BindUri method to Binding. BindUri is similar with Bind,
@@ -83,6 +85,8 @@ var (
YAML = yamlBinding{}
Uri = uriBinding{}
Header = headerBinding{}
+ Request = requestBinding{}
+ Cookie = cookieBinding{}
)
// Default returns the appropriate Binding instance based on the HTTP method
diff --git a/binding/binding_request_test.go b/binding/binding_request_test.go
new file mode 100644
index 00000000..cce111f1
--- /dev/null
+++ b/binding/binding_request_test.go
@@ -0,0 +1,85 @@
+package binding
+
+import (
+ "net/http"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+type Params struct {
+ Name string `uri:"name"`
+ Age int `form:"age,default=18"`
+ Money int32 `form:"money" binding:"required"`
+ Authorization string `cookie:"Authorization"`
+ UserAgent string `header:"User-Agent"`
+ Data *ParamBody `body:"body"`
+}
+
+type ParamBody struct {
+ Replicas *int32 `json:"replicas"`
+}
+
+func NewParams() *Params {
+ return &Params{
+ Data: &ParamBody{},
+ }
+}
+
+func TestBindRequest(t *testing.T) {
+ h := Request
+ assert.Equal(t, "request", h.Name())
+
+ params := NewParams()
+
+ mocks := []struct {
+ body string
+ mime string
+ method string
+ }{
+ {body: `replicas: 5`, mime: MIMEYAML, method: http.MethodPost},
+ {body: `{"replicas": 5}`, mime: MIMEJSON, method: http.MethodPut},
+ {body: `replicas=5`, mime: MIMEPOSTForm, method: http.MethodPatch},
+ {body: `replicas=5`, mime: MIMEPOSTForm, method: http.MethodGet},
+ {
+ body: `5`,
+ mime: MIMEXML2,
+ method: http.MethodDelete,
+ },
+ {
+ body: `5`,
+ mime: MIMEXML,
+ method: http.MethodDelete,
+ },
+ }
+
+ for _, mock := range mocks {
+
+ t.Run(mock.mime, func(t *testing.T) {
+ req := requestWithBody(mock.method, "/hello/:name?money=1000", mock.body)
+ mockUri := map[string][]string{
+ "name": {"zhangsan"},
+ }
+ req.Header.Add("Content-Type", mock.mime)
+ req.Header.Add("User-Agent", "go-client")
+ req.AddCookie(
+ &http.Cookie{Name: "Authorization", Value: "token 123123123"},
+ )
+
+ err := h.Bind(params, req, mockUri)
+ if err != nil {
+ panic(err)
+ }
+
+ assert.NoError(t, err)
+ assert.Equal(t, "zhangsan", params.Name) // uri
+ assert.Equal(t, 18, params.Age) // form,defualt
+ assert.Equal(t, int32(1000), params.Money) // form,required
+ assert.Equal(t, "token 123123123", params.Authorization) // cookie
+ assert.Equal(t, "go-client", params.UserAgent) // header
+ assert.Equal(t, int32(5), *params.Data.Replicas) // body,ptr
+ })
+
+ }
+
+}
diff --git a/binding/binding_test.go b/binding/binding_test.go
index 17336177..4d5273f7 100644
--- a/binding/binding_test.go
+++ b/binding/binding_test.go
@@ -785,14 +785,14 @@ func TestUriBinding(t *testing.T) {
var tag Tag
m := make(map[string][]string)
m["name"] = []string{"thinkerou"}
- assert.NoError(t, b.BindUri(m, &tag))
+ assert.NoError(t, b.Bind(m, &tag))
assert.Equal(t, "thinkerou", tag.Name)
type NotSupportStruct struct {
Name map[string]interface{} `uri:"name"`
}
var not NotSupportStruct
- assert.Error(t, b.BindUri(m, ¬))
+ assert.Error(t, b.Bind(m, ¬))
assert.Equal(t, map[string]interface{}(nil), not.Name)
}
@@ -813,7 +813,7 @@ func TestUriInnerBinding(t *testing.T) {
}
var tag Tag
- assert.NoError(t, Uri.BindUri(m, &tag))
+ assert.NoError(t, Uri.Bind(m, &tag))
assert.Equal(t, tag.Name, expectedName)
assert.Equal(t, tag.S.Age, expectedAge)
}
diff --git a/binding/cookie.go b/binding/cookie.go
new file mode 100644
index 00000000..237afb19
--- /dev/null
+++ b/binding/cookie.go
@@ -0,0 +1,27 @@
+package binding
+
+import "net/http"
+
+type cookieBinding struct{}
+
+func (cookieBinding) Name() string {
+ return "cookie"
+}
+
+func (b cookieBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := b.BindOnly(req, obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}
+
+func (cookieBinding) BindOnly(req *http.Request, obj interface{}) error {
+ cookies := req.Cookies()
+
+ form := make(map[string][]string, len(cookies))
+ for i := 0; i < len(cookies); i++ {
+ form[cookies[i].Name] = []string{cookies[i].Value}
+ }
+
+ return mapFormByTag(obj, form, "cookie")
+}
diff --git a/binding/form.go b/binding/form.go
index 040af9e2..ccd33a20 100644
--- a/binding/form.go
+++ b/binding/form.go
@@ -18,7 +18,14 @@ func (formBinding) Name() string {
return "form"
}
-func (formBinding) Bind(req *http.Request, obj interface{}) error {
+func (b formBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := b.BindOnly(req, obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}
+
+func (b formBinding) BindOnly(req *http.Request, obj interface{}) error {
if err := req.ParseForm(); err != nil {
return err
}
@@ -28,28 +35,42 @@ func (formBinding) Bind(req *http.Request, obj interface{}) error {
if err := mapForm(obj, req.Form); err != nil {
return err
}
- return validate(obj)
+ return nil
}
func (formPostBinding) Name() string {
return "form-urlencoded"
}
-func (formPostBinding) Bind(req *http.Request, obj interface{}) error {
+func (b formPostBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := b.BindOnly(req, obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}
+
+func (b formPostBinding) BindOnly(req *http.Request, obj interface{}) error {
if err := req.ParseForm(); err != nil {
return err
}
if err := mapForm(obj, req.PostForm); err != nil {
return err
}
- return validate(obj)
+ return nil
}
func (formMultipartBinding) Name() string {
return "multipart/form-data"
}
-func (formMultipartBinding) Bind(req *http.Request, obj interface{}) error {
+func (b formMultipartBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := b.BindOnly(req, obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}
+
+func (b formMultipartBinding) BindOnly(req *http.Request, obj interface{}) error {
if err := req.ParseMultipartForm(defaultMemory); err != nil {
return err
}
@@ -57,5 +78,5 @@ func (formMultipartBinding) Bind(req *http.Request, obj interface{}) error {
return err
}
- return validate(obj)
+ return nil
}
diff --git a/binding/header.go b/binding/header.go
index b99302af..def34576 100644
--- a/binding/header.go
+++ b/binding/header.go
@@ -12,15 +12,19 @@ func (headerBinding) Name() string {
return "header"
}
-func (headerBinding) Bind(req *http.Request, obj interface{}) error {
+func (b headerBinding) Bind(req *http.Request, obj interface{}) error {
- if err := mapHeader(obj, req.Header); err != nil {
+ if err := b.BindOnly(req, obj); err != nil {
return err
}
return validate(obj)
}
+func (headerBinding) BindOnly(req *http.Request, obj interface{}) error {
+ return mapHeader(obj, req.Header)
+}
+
func mapHeader(ptr interface{}, h map[string][]string) error {
return mappingByPtr(ptr, headerSource(h), "header")
}
diff --git a/binding/json.go b/binding/json.go
index 45aaa494..78300065 100644
--- a/binding/json.go
+++ b/binding/json.go
@@ -30,14 +30,33 @@ func (jsonBinding) Name() string {
return "json"
}
-func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
+func (b jsonBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := b.BindOnly(req, obj); err != nil {
+ return err
+ }
+
+ return validate(obj)
+
+}
+
+func (b jsonBinding) BindOnly(req *http.Request, obj interface{}) error {
if req == nil || req.Body == nil {
return errors.New("invalid request")
}
+
+ // data, _ := ioutil.ReadAll(req.Body)
+ // fmt.Printf("%s", data)
+
return decodeJSON(req.Body, obj)
}
-func (jsonBinding) BindBody(body []byte, obj interface{}) error {
+func (b jsonBinding) BindBody(body []byte, obj interface{}) error {
+ if err := b.BindBodyOnly(body, obj); err != nil {
+ return err
+ }
+ return validate(obj)
+}
+func (b jsonBinding) BindBodyOnly(body []byte, obj interface{}) error {
return decodeJSON(bytes.NewReader(body), obj)
}
@@ -52,5 +71,5 @@ func decodeJSON(r io.Reader, obj interface{}) error {
if err := decoder.Decode(obj); err != nil {
return err
}
- return validate(obj)
+ return nil
}
diff --git a/binding/msgpack.go b/binding/msgpack.go
index 2a442996..d79e6cc0 100644
--- a/binding/msgpack.go
+++ b/binding/msgpack.go
@@ -21,18 +21,31 @@ func (msgpackBinding) Name() string {
return "msgpack"
}
-func (msgpackBinding) Bind(req *http.Request, obj interface{}) error {
+func (b msgpackBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := b.BindOnly(req, obj); err != nil {
+ return err
+ }
+
+ return validate(obj)
+}
+
+func (b msgpackBinding) BindOnly(req *http.Request, obj interface{}) error {
return decodeMsgPack(req.Body, obj)
}
-func (msgpackBinding) BindBody(body []byte, obj interface{}) error {
+func (b msgpackBinding) BindBody(body []byte, obj interface{}) error {
+ if err := b.BindBodyOnly(body, obj); err != nil {
+ return err
+ }
+
+ return validate(obj)
+}
+
+func (b msgpackBinding) BindBodyOnly(body []byte, obj interface{}) error {
return decodeMsgPack(bytes.NewReader(body), obj)
}
func decodeMsgPack(r io.Reader, obj interface{}) error {
cdc := new(codec.MsgpackHandle)
- if err := codec.NewDecoder(r, cdc).Decode(&obj); err != nil {
- return err
- }
- return validate(obj)
+ return codec.NewDecoder(r, cdc).Decode(&obj)
}
diff --git a/binding/protobuf.go b/binding/protobuf.go
index f9ece928..ca3aaa27 100644
--- a/binding/protobuf.go
+++ b/binding/protobuf.go
@@ -18,14 +18,22 @@ func (protobufBinding) Name() string {
}
func (b protobufBinding) Bind(req *http.Request, obj interface{}) error {
+ return b.BindOnly(req, obj)
+}
+
+func (b protobufBinding) BindOnly(req *http.Request, obj interface{}) error {
buf, err := ioutil.ReadAll(req.Body)
if err != nil {
return err
}
- return b.BindBody(buf, obj)
+ return b.BindBodyOnly(buf, obj)
}
-func (protobufBinding) BindBody(body []byte, obj interface{}) error {
+func (b protobufBinding) BindBody(body []byte, obj interface{}) error {
+ return b.BindBodyOnly(body, obj)
+}
+
+func (protobufBinding) BindBodyOnly(body []byte, obj interface{}) error {
if err := proto.Unmarshal(body, obj.(proto.Message)); err != nil {
return err
}
diff --git a/binding/query.go b/binding/query.go
index 219743f2..4b73312b 100644
--- a/binding/query.go
+++ b/binding/query.go
@@ -12,10 +12,18 @@ func (queryBinding) Name() string {
return "query"
}
-func (queryBinding) Bind(req *http.Request, obj interface{}) error {
+func (b queryBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := b.BindOnly(req, obj); err != nil {
+ return err
+ }
+
+ return validate(obj)
+}
+
+func (queryBinding) BindOnly(req *http.Request, obj interface{}) error {
values := req.URL.Query()
if err := mapForm(obj, values); err != nil {
return err
}
- return validate(obj)
+ return nil
}
diff --git a/binding/request.go b/binding/request.go
new file mode 100644
index 00000000..49f63cf3
--- /dev/null
+++ b/binding/request.go
@@ -0,0 +1,75 @@
+package binding
+
+import (
+ "net/http"
+ "reflect"
+)
+
+type requestBinding struct{}
+
+func (requestBinding) Name() string {
+ return "request"
+}
+
+func (b requestBinding) Bind(obj interface{}, req *http.Request, form map[string][]string) error {
+ if err := b.BindOnly(obj, req, form); err != nil {
+ return err
+ }
+
+ return validate(obj)
+}
+
+func (b requestBinding) BindOnly(obj interface{}, req *http.Request, uriMap map[string][]string) error {
+
+ if err := Uri.BindOnly(uriMap, obj); err != nil {
+ return err
+ }
+
+ binders := []interface{}{Header, Query, Cookie}
+ for _, binder := range binders {
+ if b, ok := binder.(Binding); ok {
+ if err := b.BindOnly(req, obj); err != nil {
+ return err
+ }
+ }
+ }
+
+ // body decode
+ bodyPtr := reflectx(obj)
+
+ // default json
+ contentType := req.Header.Get("Content-Type")
+ if contentType == "" {
+ contentType = MIMEJSON
+ }
+ bb := Default(req.Method, contentType)
+ return bb.BindOnly(req, bodyPtr)
+
+}
+
+func reflectx(obj interface{}) interface{} {
+
+ // pre-check obj
+ rv := reflect.ValueOf(obj)
+ rv = reflect.Indirect(rv)
+ if rv.Kind() != reflect.Struct {
+ return nil
+ }
+
+ typ := rv.Type()
+ for i := 0; i < rv.NumField(); i++ {
+ tf := typ.Field(i)
+ vf := rv.Field(i)
+ _, ok := tf.Tag.Lookup("body")
+ if !ok {
+ continue
+ }
+
+ // find body struct
+ if vf.Kind() == reflect.Ptr && vf.Elem().Kind() == reflect.Struct {
+ return vf.Interface()
+ }
+ }
+
+ return nil
+}
diff --git a/binding/uri.go b/binding/uri.go
index f91ec381..203e8557 100644
--- a/binding/uri.go
+++ b/binding/uri.go
@@ -10,9 +10,13 @@ func (uriBinding) Name() string {
return "uri"
}
-func (uriBinding) BindUri(m map[string][]string, obj interface{}) error {
+func (uriBinding) Bind(m map[string][]string, obj interface{}) error {
if err := mapUri(obj, m); err != nil {
return err
}
return validate(obj)
}
+
+func (uriBinding) BindOnly(m map[string][]string, obj interface{}) error {
+ return mapUri(obj, m)
+}
diff --git a/binding/xml.go b/binding/xml.go
index 4e901149..cbd17a0d 100644
--- a/binding/xml.go
+++ b/binding/xml.go
@@ -18,16 +18,35 @@ func (xmlBinding) Name() string {
}
func (xmlBinding) Bind(req *http.Request, obj interface{}) error {
+ err := decodeXML(req.Body, obj)
+ if err != nil {
+ return err
+ }
+
+ return validate(obj)
+}
+
+func (xmlBinding) BindOnly(req *http.Request, obj interface{}) error {
return decodeXML(req.Body, obj)
}
-func (xmlBinding) BindBody(body []byte, obj interface{}) error {
+func (b xmlBinding) BindBody(body []byte, obj interface{}) error {
+ if err := b.BindBodyOnly(body, obj); err != nil {
+ return err
+ }
+
+ return validate(obj)
+}
+
+func (xmlBinding) BindBodyOnly(body []byte, obj interface{}) error {
return decodeXML(bytes.NewReader(body), obj)
}
+
func decodeXML(r io.Reader, obj interface{}) error {
decoder := xml.NewDecoder(r)
if err := decoder.Decode(obj); err != nil {
return err
}
- return validate(obj)
+
+ return nil
}
diff --git a/binding/yaml.go b/binding/yaml.go
index a2d36d6a..65a18d53 100644
--- a/binding/yaml.go
+++ b/binding/yaml.go
@@ -18,18 +18,31 @@ func (yamlBinding) Name() string {
return "yaml"
}
-func (yamlBinding) Bind(req *http.Request, obj interface{}) error {
+func (b yamlBinding) Bind(req *http.Request, obj interface{}) error {
+ if err := b.BindOnly(req, obj); err != nil {
+ return err
+ }
+
+ return validate(obj)
+}
+
+func (yamlBinding) BindOnly(req *http.Request, obj interface{}) error {
return decodeYAML(req.Body, obj)
}
-func (yamlBinding) BindBody(body []byte, obj interface{}) error {
+func (b yamlBinding) BindBody(body []byte, obj interface{}) error {
+ if err := b.BindBodyOnly(body, obj); err != nil {
+ return err
+ }
+
+ return validate(obj)
+}
+
+func (yamlBinding) BindBodyOnly(body []byte, obj interface{}) error {
return decodeYAML(bytes.NewReader(body), obj)
}
func decodeYAML(r io.Reader, obj interface{}) error {
decoder := yaml.NewDecoder(r)
- if err := decoder.Decode(obj); err != nil {
- return err
- }
- return validate(obj)
+ return decoder.Decode(obj)
}
diff --git a/context.go b/context.go
index 1a953006..35b13349 100644
--- a/context.go
+++ b/context.go
@@ -631,6 +631,11 @@ func (c *Context) BindHeader(obj interface{}) error {
return c.MustBindWith(obj, binding.Header)
}
+// BindCookie is a shortcut for c.MustBindWith(obj, binding.Cookie).
+func (c *Context) BindCookie(obj interface{}) error {
+ return c.MustBindWith(obj, binding.Cookie)
+}
+
// BindUri binds the passed struct pointer using binding.Uri.
// It will abort the request with HTTP 400 if any error occurs.
func (c *Context) BindUri(obj interface{}) error {
@@ -641,6 +646,16 @@ func (c *Context) BindUri(obj interface{}) error {
return nil
}
+// BindRequest binds the passed struct pointer using binding.Request.
+// It will abort the request with HTTP 400 if any error occurs.
+func (c *Context) BindRequest(obj interface{}) error {
+ if err := c.ShouldBindRequest(obj); err != nil {
+ c.AbortWithError(http.StatusBadRequest, err).SetType(ErrorTypeBind)
+ return err
+ }
+ return nil
+}
+
// MustBindWith binds the passed struct pointer using the specified binding engine.
// It will abort the request with HTTP 400 if any error occurs.
// See the binding package.
@@ -690,13 +705,46 @@ func (c *Context) ShouldBindHeader(obj interface{}) error {
return c.ShouldBindWith(obj, binding.Header)
}
+// ShouldBindCookie is a shortcut for c.ShouldBindWith(obj, binding.Cookie).
+func (c *Context) ShouldBindCookie(obj interface{}) error {
+ return c.ShouldBindWith(obj, binding.Cookie)
+}
+
// ShouldBindUri binds the passed struct pointer using the specified binding engine.
func (c *Context) ShouldBindUri(obj interface{}) error {
m := make(map[string][]string)
for _, v := range c.Params {
m[v.Key] = []string{v.Value}
}
- return binding.Uri.BindUri(m, obj)
+ return binding.Uri.Bind(m, obj)
+}
+
+// ShouldBindRequest binds the passed struct pointer using the specified binding engine.
+// including
+// `uri`,
+// `query`
+// `header` and
+// `body data` with tag `body:"body"`
+// and it's decoder is decided by header `Content-Type` value
+//
+// type Params struct {
+// Name string `uri:"name"`
+// Age string `form:"age" default:"100"`
+// Money string `form:"money" binding:"required"`
+// Authorization string `cookie:"Authorization"`
+// UserAgent string `header:"User-Agent"`
+// Data *ParamBody `body:"body" mime:"json"`
+// }
+// type ParamBody struct {
+// Replicas *int32 `json:"replicas"`
+// }
+func (c *Context) ShouldBindRequest(obj interface{}) error {
+ params := make(map[string][]string)
+ for _, v := range c.Params {
+ params[v.Key] = []string{v.Value}
+ }
+
+ return binding.Request.Bind(obj, c.Request, params)
}
// ShouldBindWith binds the passed struct pointer using the specified binding engine.