Proposal:Add Bind() method for web.Controller
This commit is contained in:
parent
29fd8719a8
commit
8b92ed6504
@ -33,8 +33,8 @@
|
||||
- Improve: Avoid ignoring mistakes that need attention [4548](https://github.com/beego/beego/pull/4548)
|
||||
- Integration: DeepSource [4560](https://github.com/beego/beego/pull/4560)
|
||||
- Integration: Remove unnecessary function call [4577](https://github.com/beego/beego/pull/4577)
|
||||
|
||||
|
||||
- Feature issue #4402 finish router get example. [4416](https://github.com/beego/beego/pull/4416)
|
||||
- Proposal: Add Bind() method for web.Controller [4491](https://github.com/beego/beego/issues/4491)
|
||||
|
||||
## Fix Sonar
|
||||
- [4473](https://github.com/beego/beego/pull/4473)
|
||||
|
||||
@ -17,8 +17,12 @@ package web
|
||||
import (
|
||||
"bytes"
|
||||
context2 "context"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"gopkg.in/yaml.v2"
|
||||
"html/template"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
@ -147,6 +151,12 @@ type ControllerInterface interface {
|
||||
CheckXSRFCookie() bool
|
||||
HandlerFunc(fn string) bool
|
||||
URLMapping()
|
||||
Bind(obj interface{}) error
|
||||
BindJson(obj interface{}) error
|
||||
BindXML(obj interface{}) error
|
||||
BindForm(obj interface{}) error
|
||||
BindProtobuf(obj interface{}) error
|
||||
BindYAML(obj interface{}) error
|
||||
}
|
||||
|
||||
// Init generates default values of controller operations.
|
||||
@ -239,6 +249,48 @@ func (c *Controller) HandlerFunc(fnname string) bool {
|
||||
// URLMapping register the internal Controller router.
|
||||
func (c *Controller) URLMapping() {}
|
||||
|
||||
func (c *Controller) Bind(obj interface{}) error {
|
||||
ct := c.Ctx.Request.Header["Content-Type"]
|
||||
i, l := 0, len(ct[0])
|
||||
for ; i < l && ct[0][i] != ';'; i++ {
|
||||
}
|
||||
switch ct[0][0:i] {
|
||||
case "application/json":
|
||||
return c.BindJson(obj)
|
||||
case "application/xml", "text/xml":
|
||||
return c.BindXML(obj)
|
||||
case "application/x-www-form-urlencoded":
|
||||
return c.BindForm(obj)
|
||||
case "application/x-protobuf":
|
||||
return c.BindProtobuf(obj)
|
||||
case "application/x-yaml":
|
||||
return c.BindYAML(obj)
|
||||
default:
|
||||
return errors.New("Unsupported Content-Type:" + ct[0])
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Controller) BindYAML(obj interface{}) error {
|
||||
return yaml.Unmarshal(c.Ctx.Input.RequestBody, obj)
|
||||
}
|
||||
|
||||
func (c *Controller) BindForm(obj interface{}) error {
|
||||
return c.ParseForm(obj)
|
||||
}
|
||||
|
||||
func (c *Controller) BindJson(obj interface{}) error {
|
||||
return json.Unmarshal(c.Ctx.Input.RequestBody, obj)
|
||||
}
|
||||
|
||||
func (c *Controller) BindProtobuf(obj interface{}) error {
|
||||
return proto.Unmarshal(c.Ctx.Input.RequestBody, obj.(proto.Message))
|
||||
}
|
||||
|
||||
func (c *Controller) BindXML(obj interface{}) error {
|
||||
return xml.Unmarshal(c.Ctx.Input.RequestBody, obj)
|
||||
}
|
||||
|
||||
|
||||
// Mapping the method to function
|
||||
func (c *Controller) Mapping(method string, fn func()) {
|
||||
c.methodMapping[method] = fn
|
||||
|
||||
@ -15,7 +15,10 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
@ -180,3 +183,50 @@ func TestAdditionalViewPaths(t *testing.T) {
|
||||
ctrl.ViewPath = dir2
|
||||
ctrl.RenderString()
|
||||
}
|
||||
|
||||
func TestBindJson(t *testing.T) {
|
||||
var s struct {
|
||||
Foo string `json:"foo"`
|
||||
}
|
||||
header := map[string][]string{"Content-Type": {"application/json"}}
|
||||
request := &http.Request{Header: header}
|
||||
input := &context.BeegoInput{RequestBody: []byte(`{"foo": "FOO"}`)}
|
||||
ctx := &context.Context{Request: request, Input: input}
|
||||
ctrlr := Controller{Ctx: ctx}
|
||||
err := ctrlr.Bind(&s)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "FOO", s.Foo)
|
||||
}
|
||||
|
||||
func TestBindXML(t *testing.T) {
|
||||
|
||||
var s struct {
|
||||
Foo string `xml:"foo"`
|
||||
}
|
||||
xmlBody := `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<root>
|
||||
<foo>FOO</foo>
|
||||
</root>`
|
||||
header := map[string][]string{"Content-Type": {"text/xml"}}
|
||||
request := &http.Request{Header: header}
|
||||
input := &context.BeegoInput{RequestBody: []byte(xmlBody)}
|
||||
ctx := &context.Context{Request: request, Input: input}
|
||||
ctrlr := Controller{Ctx: ctx}
|
||||
err := ctrlr.Bind(&s)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "FOO", s.Foo)
|
||||
}
|
||||
|
||||
func TestBindYAML(t *testing.T) {
|
||||
var s struct {
|
||||
Foo string `yaml:"foo"`
|
||||
}
|
||||
header := map[string][]string{"Content-Type": {"application/x-yaml"}}
|
||||
request := &http.Request{Header: header}
|
||||
input := &context.BeegoInput{RequestBody: []byte("foo: FOO")}
|
||||
ctx := &context.Context{Request: request, Input: input}
|
||||
ctrlr := Controller{Ctx: ctx}
|
||||
err := ctrlr.Bind(&s)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "FOO", s.Foo)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user