diff --git a/binding/binding.go b/binding/binding.go
index 036b329b..94723879 100644
--- a/binding/binding.go
+++ b/binding/binding.go
@@ -73,18 +73,18 @@ var Validator StructValidator = &defaultValidator{}
// These implement the Binding interface and can be used to bind the data
// present in the request to struct instances.
var (
- JSON = jsonBinding{}
- XML = xmlBinding{}
- Form = formBinding{}
- Query = queryBinding{}
- FormPost = formPostBinding{}
- FormMultipart = formMultipartBinding{}
- ProtoBuf = protobufBinding{}
- MsgPack = msgpackBinding{}
- YAML = yamlBinding{}
- Uri = uriBinding{}
- Header = headerBinding{}
- TOML = tomlBinding{}
+ JSON BindingBody = jsonBinding{}
+ XML BindingBody = xmlBinding{}
+ Form Binding = formBinding{}
+ Query Binding = queryBinding{}
+ FormPost Binding = formPostBinding{}
+ FormMultipart Binding = formMultipartBinding{}
+ ProtoBuf BindingBody = protobufBinding{}
+ MsgPack BindingBody = msgpackBinding{}
+ YAML BindingBody = yamlBinding{}
+ Uri BindingUri = uriBinding{}
+ Header Binding = headerBinding{}
+ TOML BindingBody = tomlBinding{}
)
// Default returns the appropriate Binding instance based on the HTTP method
diff --git a/context.go b/context.go
index 3a9608d5..afc3c353 100644
--- a/context.go
+++ b/context.go
@@ -774,6 +774,26 @@ func (c *Context) ShouldBindBodyWith(obj any, bb binding.BindingBody) (err error
return bb.BindBody(body, obj)
}
+// ShouldBindBodyWithJSON is a shortcut for c.ShouldBindBodyWith(obj, binding.JSON).
+func (c *Context) ShouldBindBodyWithJSON(obj any) error {
+ return c.ShouldBindBodyWith(obj, binding.JSON)
+}
+
+// ShouldBindBodyWithXML is a shortcut for c.ShouldBindBodyWith(obj, binding.XML).
+func (c *Context) ShouldBindBodyWithXML(obj any) error {
+ return c.ShouldBindBodyWith(obj, binding.XML)
+}
+
+// ShouldBindBodyWithYAML is a shortcut for c.ShouldBindBodyWith(obj, binding.YAML).
+func (c *Context) ShouldBindBodyWithYAML(obj any) error {
+ return c.ShouldBindBodyWith(obj, binding.YAML)
+}
+
+// ShouldBindBodyWithTOML is a shortcut for c.ShouldBindBodyWith(obj, binding.TOML).
+func (c *Context) ShouldBindBodyWithTOML(obj any) error {
+ return c.ShouldBindBodyWith(obj, binding.TOML)
+}
+
// ClientIP implements one best effort algorithm to return the real client IP.
// It calls c.RemoteIP() under the hood, to check if the remote IP is a trusted proxy or not.
// If it is it will then try to parse the headers defined in Engine.RemoteIPHeaders (defaulting to [X-Forwarded-For, X-Real-Ip]).
diff --git a/context_test.go b/context_test.go
index 9c1717ed..e9bbae52 100644
--- a/context_test.go
+++ b/context_test.go
@@ -1977,6 +1977,263 @@ func TestContextShouldBindBodyWith(t *testing.T) {
}
}
+func TestContextShouldBindBodyWithJSON(t *testing.T) {
+ for _, tt := range []struct {
+ name string
+ bindingBody binding.BindingBody
+ body string
+ }{
+ {
+ name: " JSON & JSON-BODY ",
+ bindingBody: binding.JSON,
+ body: `{"foo":"FOO"}`,
+ },
+ {
+ name: " JSON & XML-BODY ",
+ bindingBody: binding.XML,
+ body: `
+
+FOO
+`,
+ },
+ {
+ name: " JSON & YAML-BODY ",
+ bindingBody: binding.YAML,
+ body: `foo: FOO`,
+ },
+ {
+ name: " JSON & TOM-BODY ",
+ bindingBody: binding.TOML,
+ body: `foo=FOO`,
+ },
+ } {
+ t.Logf("testing: %s", tt.name)
+
+ w := httptest.NewRecorder()
+ c, _ := CreateTestContext(w)
+
+ c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
+
+ type typeJSON struct {
+ Foo string `json:"foo" binding:"required"`
+ }
+ objJSON := typeJSON{}
+
+ if tt.bindingBody == binding.JSON {
+ assert.NoError(t, c.ShouldBindBodyWithJSON(&objJSON))
+ assert.Equal(t, typeJSON{"FOO"}, objJSON)
+ }
+
+ if tt.bindingBody == binding.XML {
+ assert.Error(t, c.ShouldBindBodyWithJSON(&objJSON))
+ assert.Equal(t, typeJSON{}, objJSON)
+ }
+
+ if tt.bindingBody == binding.YAML {
+ assert.Error(t, c.ShouldBindBodyWithJSON(&objJSON))
+ assert.Equal(t, typeJSON{}, objJSON)
+ }
+
+ if tt.bindingBody == binding.TOML {
+ assert.Error(t, c.ShouldBindBodyWithJSON(&objJSON))
+ assert.Equal(t, typeJSON{}, objJSON)
+ }
+ }
+}
+
+func TestContextShouldBindBodyWithXML(t *testing.T) {
+ for _, tt := range []struct {
+ name string
+ bindingBody binding.BindingBody
+ body string
+ }{
+ {
+ name: " XML & JSON-BODY ",
+ bindingBody: binding.JSON,
+ body: `{"foo":"FOO"}`,
+ },
+ {
+ name: " XML & XML-BODY ",
+ bindingBody: binding.XML,
+ body: `
+
+FOO
+`,
+ },
+ {
+ name: " XML & YAML-BODY ",
+ bindingBody: binding.YAML,
+ body: `foo: FOO`,
+ },
+ {
+ name: " XML & TOM-BODY ",
+ bindingBody: binding.TOML,
+ body: `foo=FOO`,
+ },
+ } {
+ t.Logf("testing: %s", tt.name)
+
+ w := httptest.NewRecorder()
+ c, _ := CreateTestContext(w)
+
+ c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
+
+ type typeXML struct {
+ Foo string `xml:"foo" binding:"required"`
+ }
+ objXML := typeXML{}
+
+ if tt.bindingBody == binding.JSON {
+ assert.Error(t, c.ShouldBindBodyWithXML(&objXML))
+ assert.Equal(t, typeXML{}, objXML)
+ }
+
+ if tt.bindingBody == binding.XML {
+ assert.NoError(t, c.ShouldBindBodyWithXML(&objXML))
+ assert.Equal(t, typeXML{"FOO"}, objXML)
+ }
+
+ if tt.bindingBody == binding.YAML {
+ assert.Error(t, c.ShouldBindBodyWithXML(&objXML))
+ assert.Equal(t, typeXML{}, objXML)
+ }
+
+ if tt.bindingBody == binding.TOML {
+ assert.Error(t, c.ShouldBindBodyWithXML(&objXML))
+ assert.Equal(t, typeXML{}, objXML)
+ }
+ }
+}
+
+func TestContextShouldBindBodyWithYAML(t *testing.T) {
+ for _, tt := range []struct {
+ name string
+ bindingBody binding.BindingBody
+ body string
+ }{
+ {
+ name: " YAML & JSON-BODY ",
+ bindingBody: binding.JSON,
+ body: `{"foo":"FOO"}`,
+ },
+ {
+ name: " YAML & XML-BODY ",
+ bindingBody: binding.XML,
+ body: `
+
+FOO
+`,
+ },
+ {
+ name: " YAML & YAML-BODY ",
+ bindingBody: binding.YAML,
+ body: `foo: FOO`,
+ },
+ {
+ name: " YAML & TOM-BODY ",
+ bindingBody: binding.TOML,
+ body: `foo=FOO`,
+ },
+ } {
+ t.Logf("testing: %s", tt.name)
+
+ w := httptest.NewRecorder()
+ c, _ := CreateTestContext(w)
+
+ c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
+
+ type typeYAML struct {
+ Foo string `yaml:"foo" binding:"required"`
+ }
+ objYAML := typeYAML{}
+
+ // YAML belongs to a super collection of JSON, so JSON can be parsed by YAML
+ if tt.bindingBody == binding.JSON {
+ assert.NoError(t, c.ShouldBindBodyWithYAML(&objYAML))
+ assert.Equal(t, typeYAML{"FOO"}, objYAML)
+ }
+
+ if tt.bindingBody == binding.XML {
+ assert.Error(t, c.ShouldBindBodyWithYAML(&objYAML))
+ assert.Equal(t, typeYAML{}, objYAML)
+ }
+
+ if tt.bindingBody == binding.YAML {
+ assert.NoError(t, c.ShouldBindBodyWithYAML(&objYAML))
+ assert.Equal(t, typeYAML{"FOO"}, objYAML)
+ }
+
+ if tt.bindingBody == binding.TOML {
+ assert.Error(t, c.ShouldBindBodyWithYAML(&objYAML))
+ assert.Equal(t, typeYAML{}, objYAML)
+ }
+ }
+}
+
+func TestContextShouldBindBodyWithTOML(t *testing.T) {
+ for _, tt := range []struct {
+ name string
+ bindingBody binding.BindingBody
+ body string
+ }{
+ {
+ name: " TOML & JSON-BODY ",
+ bindingBody: binding.JSON,
+ body: `{"foo":"FOO"}`,
+ },
+ {
+ name: " TOML & XML-BODY ",
+ bindingBody: binding.XML,
+ body: `
+
+FOO
+`,
+ },
+ {
+ name: " TOML & YAML-BODY ",
+ bindingBody: binding.YAML,
+ body: `foo: FOO`,
+ },
+ {
+ name: " TOML & TOM-BODY ",
+ bindingBody: binding.TOML,
+ body: `foo = 'FOO'`,
+ },
+ } {
+ t.Logf("testing: %s", tt.name)
+
+ w := httptest.NewRecorder()
+ c, _ := CreateTestContext(w)
+
+ c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(tt.body))
+
+ type typeTOML struct {
+ Foo string `toml:"foo" binding:"required"`
+ }
+ objTOML := typeTOML{}
+
+ if tt.bindingBody == binding.JSON {
+ assert.Error(t, c.ShouldBindBodyWithTOML(&objTOML))
+ assert.Equal(t, typeTOML{}, objTOML)
+ }
+
+ if tt.bindingBody == binding.XML {
+ assert.Error(t, c.ShouldBindBodyWithTOML(&objTOML))
+ assert.Equal(t, typeTOML{}, objTOML)
+ }
+
+ if tt.bindingBody == binding.YAML {
+ assert.Error(t, c.ShouldBindBodyWithTOML(&objTOML))
+ assert.Equal(t, typeTOML{}, objTOML)
+ }
+
+ if tt.bindingBody == binding.TOML {
+ assert.NoError(t, c.ShouldBindBodyWithTOML(&objTOML))
+ assert.Equal(t, typeTOML{"FOO"}, objTOML)
+ }
+ }
+}
+
func TestContextGolangContext(t *testing.T) {
c, _ := CreateTestContext(httptest.NewRecorder())
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString("{\"foo\":\"bar\", \"bar\":\"foo\"}"))
diff --git a/docs/doc.md b/docs/doc.md
index df006e87..70c9f275 100644
--- a/docs/doc.md
+++ b/docs/doc.md
@@ -1956,7 +1956,12 @@ func SomeHandler(c *gin.Context) {
}
```
-For this, you can use `c.ShouldBindBodyWith`.
+For this, you can use `c.ShouldBindBodyWith` or shortcuts.
+
+- `c.ShouldBindBodyWithJSON` is a shortcut for c.ShouldBindBodyWith(obj, binding.JSON).
+- `c.ShouldBindBodyWithXML` is a shortcut for c.ShouldBindBodyWith(obj, binding.XML).
+- `c.ShouldBindBodyWithYAML` is a shortcut for c.ShouldBindBodyWith(obj, binding.YAML).
+- `c.ShouldBindBodyWithTOML` is a shortcut for c.ShouldBindBodyWith(obj, binding.TOML).
```go
func SomeHandler(c *gin.Context) {
@@ -1969,7 +1974,7 @@ func SomeHandler(c *gin.Context) {
} else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
c.String(http.StatusOK, `the body should be formB JSON`)
// And it can accepts other formats
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ } else if errB2 := c.ShouldBindBodyWithXML(&objB); errB2 == nil {
c.String(http.StatusOK, `the body should be formB XML`)
} else {
...