diff --git a/hero/binding.go b/hero/binding.go index a6ec405f..0c7958a2 100644 --- a/hero/binding.go +++ b/hero/binding.go @@ -209,7 +209,7 @@ func getBindingsFor(inputs []reflect.Type, deps []*Dependency, paramsCount int) } // else add builtin bindings that may be registered by user too, but they didn't. - if indirectType(in).Kind() == reflect.Struct { + if isPayloadType(in) { bindings = append(bindings, payloadBinding(i, in)) continue } @@ -219,6 +219,15 @@ func getBindingsFor(inputs []reflect.Type, deps []*Dependency, paramsCount int) return } +func isPayloadType(in reflect.Type) bool { + switch indirectType(in).Kind() { + case reflect.Struct, reflect.Slice: + return true + default: + return false + } +} + func getBindingsForFunc(fn reflect.Value, dependencies []*Dependency, paramsCount int) []*binding { fnTyp := fn.Type() if !isFunc(fnTyp) { @@ -331,9 +340,15 @@ func payloadBinding(index int, typ reflect.Type) *binding { } } - newValue = reflect.New(indirectType(input.Type)) + if input.Type.Kind() == reflect.Slice { + newValue = reflect.New(reflect.SliceOf(indirectType(input.Type))) + } else { + newValue = reflect.New(indirectType(input.Type)) + } + ptr := newValue.Interface() err = ctx.ReadBody(ptr) + if !wasPtr { newValue = newValue.Elem() } diff --git a/mvc/controller_test.go b/mvc/controller_test.go index 535e5fd2..272f9b87 100644 --- a/mvc/controller_test.go +++ b/mvc/controller_test.go @@ -711,23 +711,34 @@ func TestControllerOverlapping(t *testing.T) { type testControllerMethodHandlerBindStruct struct{} -type queryData struct { +type bindStructData struct { Name string `json:"name" url:"name"` } -func (*testControllerMethodHandlerBindStruct) Any(data queryData) queryData { +func (*testControllerMethodHandlerBindStruct) Any(data bindStructData) bindStructData { + return data +} + +func (*testControllerMethodHandlerBindStruct) PostByProducts(id uint64, data []bindStructData) []bindStructData { return data } func TestControllerMethodHandlerBindStruct(t *testing.T) { app := iris.New() - New(app).Handle(new(testControllerMethodHandlerBindStruct)) + m := New(app.Party("/data")) + m.HandleError(func(ctx iris.Context, err error) { + t.Fatalf("Path: %s, Error: %v", ctx.Path(), err) + }) - data := iris.Map{"name": "kataras"} + m.Handle(new(testControllerMethodHandlerBindStruct)) + + data := bindStructData{Name: "kataras"} + manyData := []bindStructData{{"kataras"}, {"john doe"}} e := httptest.New(t, app) - e.GET("/").WithQueryObject(data).Expect().Status(httptest.StatusOK).JSON().Equal(data) - e.PATCH("/").WithJSON(data).Expect().Status(httptest.StatusOK).JSON().Equal(data) + e.GET("/data").WithQueryObject(data).Expect().Status(httptest.StatusOK).JSON().Equal(data) + e.PATCH("/data").WithJSON(data).Expect().Status(httptest.StatusOK).JSON().Equal(data) + e.POST("/data/42/products").WithJSON(manyData).Expect().Status(httptest.StatusOK).JSON().Equal(manyData) // more tests inside the hero package itself. }