mirror of
https://github.com/labstack/echo.git
synced 2024-12-24 20:14:31 +02:00
Fix #1858: Add query params binding support for anonymous struct pointer filed
This commit is contained in:
parent
2943a32005
commit
18d7fe11df
9
bind.go
9
bind.go
@ -144,11 +144,20 @@ func (b *DefaultBinder) bindData(destination interface{}, data map[string][]stri
|
|||||||
for i := 0; i < typ.NumField(); i++ {
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
typeField := typ.Field(i)
|
typeField := typ.Field(i)
|
||||||
structField := val.Field(i)
|
structField := val.Field(i)
|
||||||
|
if typeField.Anonymous {
|
||||||
|
for structField.Kind() == reflect.Ptr {
|
||||||
|
structField = structField.Elem()
|
||||||
|
}
|
||||||
|
}
|
||||||
if !structField.CanSet() {
|
if !structField.CanSet() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
structFieldKind := structField.Kind()
|
structFieldKind := structField.Kind()
|
||||||
inputFieldName := typeField.Tag.Get(tag)
|
inputFieldName := typeField.Tag.Get(tag)
|
||||||
|
if typeField.Anonymous && structField.Kind() == reflect.Struct && inputFieldName != "" {
|
||||||
|
// if anonymous struct, ignore custom tag
|
||||||
|
inputFieldName = ""
|
||||||
|
}
|
||||||
|
|
||||||
if inputFieldName == "" {
|
if inputFieldName == "" {
|
||||||
// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contains fields with tags).
|
// If tag is nil, we inspect if the field is a not BindUnmarshaler struct and try to bind data into it (might contains fields with tags).
|
||||||
|
45
bind_test.go
45
bind_test.go
@ -100,6 +100,9 @@ type (
|
|||||||
Struct struct {
|
Struct struct {
|
||||||
Foo string
|
Foo string
|
||||||
}
|
}
|
||||||
|
Bar struct {
|
||||||
|
Baz int `json:"baz" query:"baz"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *Timestamp) UnmarshalParam(src string) error {
|
func (t *Timestamp) UnmarshalParam(src string) error {
|
||||||
@ -330,6 +333,48 @@ func TestBindUnmarshalParamPtr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBindUnmarshalParamAnonymousFieldPtr(t *testing.T) {
|
||||||
|
e := New()
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "/?baz=1", nil)
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
c := e.NewContext(req, rec)
|
||||||
|
result := struct {
|
||||||
|
*Bar
|
||||||
|
}{&Bar{}}
|
||||||
|
err := c.Bind(&result)
|
||||||
|
if assert.NoError(t, err) {
|
||||||
|
assert.Equal(t, 1, result.Baz)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBindUnmarshalParamAnonymousFieldPtrNil(t *testing.T) {
|
||||||
|
e := New()
|
||||||
|
req := httptest.NewRequest(http.MethodGet, "/?baz=1", nil)
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
c := e.NewContext(req, rec)
|
||||||
|
result := struct {
|
||||||
|
*Bar
|
||||||
|
}{}
|
||||||
|
err := c.Bind(&result)
|
||||||
|
if assert.NoError(t, err) {
|
||||||
|
assert.Nil(t, result.Bar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBindUnmarshalParamAnonymousFieldPtrCustomTag(t *testing.T) {
|
||||||
|
e := New()
|
||||||
|
req := httptest.NewRequest(http.MethodGet, `/?bar={"baz":100}&baz=1`, nil)
|
||||||
|
rec := httptest.NewRecorder()
|
||||||
|
c := e.NewContext(req, rec)
|
||||||
|
result := struct {
|
||||||
|
*Bar `json:"bar" query:"bar"`
|
||||||
|
}{&Bar{}}
|
||||||
|
err := c.Bind(&result)
|
||||||
|
if assert.NoError(t, err) {
|
||||||
|
assert.Equal(t, 1, result.Baz)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBindUnmarshalTextPtr(t *testing.T) {
|
func TestBindUnmarshalTextPtr(t *testing.T) {
|
||||||
e := New()
|
e := New()
|
||||||
req := httptest.NewRequest(GET, "/?ts=2016-12-06T19:09:05Z", nil)
|
req := httptest.NewRequest(GET, "/?ts=2016-12-06T19:09:05Z", nil)
|
||||||
|
Loading…
Reference in New Issue
Block a user