diff --git a/context/context.go b/context/context.go index 352a84579..8e2ba0547 100644 --- a/context/context.go +++ b/context/context.go @@ -1909,8 +1909,6 @@ func (ctx *Context) ReadForm(formObject interface{}) error { } // ReadQuery binds url query to "ptr". The struct field tag is "url". -// If a client sent an unknown field, this method will return an error, -// in order to ignore that error use the `err != nil && !iris.IsErrPath(err)`. // // Example: https://github.com/kataras/iris/blob/master/_examples/request-body/read-query/main.go func (ctx *Context) ReadQuery(ptr interface{}) error { @@ -1980,6 +1978,16 @@ func (ctx *Context) ReadMsgPack(ptr interface{}) error { // JSON, Protobuf, MsgPack, XML, YAML, MultipartForm and binds the result to the "ptr". func (ctx *Context) ReadBody(ptr interface{}) error { if ctx.Method() == http.MethodGet { + if ctx.Request().URL.RawQuery != "" { + // try read from query. + return ctx.ReadQuery(ptr) + } + + // otherwise use the ReadForm, + // it's actually the same except + // ReadQuery will not fire errors on: + // 1. unknown or empty url query parameters + // 2. empty query or form (if FireEmptyFormError is enabled). return ctx.ReadForm(ptr) } diff --git a/go.mod b/go.mod index bd9bb3578..cb623367c 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/iris-contrib/httpexpect/v2 v2.0.5 github.com/iris-contrib/jade v1.1.4 github.com/iris-contrib/pongo2 v0.0.1 - github.com/iris-contrib/schema v0.0.1 + github.com/iris-contrib/schema v0.0.2 github.com/json-iterator/go v1.1.10 github.com/kataras/golog v0.0.18 github.com/kataras/neffos v0.0.16 diff --git a/hero/binding.go b/hero/binding.go index df5bb8acc..18620cc3d 100644 --- a/hero/binding.go +++ b/hero/binding.go @@ -281,9 +281,10 @@ func getBindingsForStruct(v reflect.Value, dependencies []*Dependency, paramsCou } exportedBindings := getBindingsFor(inputs, dependencies, paramsCount) - // fmt.Printf("Controller [%s] | Inputs length: %d vs Bindings length: %d | Stateless : %d\n", typ, n, len(exportedBindings), stateless) + // fmt.Printf("Controller [%s] | Inputs length: %d vs Bindings length: %d | NonZero: %d | Stateless : %d\n", + // typ, n, len(exportedBindings), len(nonZero), stateless) // for i, b := range exportedBindings { - // fmt.Printf("[%d] [Static=%v] %s\n", i, b.Dependency.Static, b.Dependency.DestType) + // fmt.Printf("[%d] [Static=%v] %#+v\n", i, b.Dependency.Static, b.Dependency.OriginalValue) // } if stateless == 0 && len(nonZero) >= len(exportedBindings) { @@ -332,8 +333,11 @@ func paramDependencyHandler(paramIndex int) DependencyHandler { } // registered if input parameters are more than matched dependencies. -// It binds an input to a request body based on the request content-type header (JSON, XML, YAML, Query, Form). +// It binds an input to a request body based on the request content-type header +// (JSON, Protobuf, Msgpack, XML, YAML, Query, Form). func payloadBinding(index int, typ reflect.Type) *binding { + // fmt.Printf("Register payload binding for index: %d and type: %s\n", index, typ.String()) + return &binding{ Dependency: &Dependency{ Handle: func(ctx *context.Context, input *Input) (newValue reflect.Value, err error) { diff --git a/mvc/controller.go b/mvc/controller.go index 963ddc41a..939a6dcb6 100644 --- a/mvc/controller.go +++ b/mvc/controller.go @@ -407,7 +407,11 @@ func (c *ControllerActivator) handlerOf(relPath, methodName string) context.Hand // c.injector.Container.GetErrorHandler(ctx).HandleError(ctx, err) // } c.injector.Container.GetErrorHandler(ctx).HandleError(ctx, err) - return + // allow skipping struct field bindings + // errors by a custom error handler. + if ctx.IsStopped() { + return + } } b := ctrl.Interface().(BaseController)