From 75d7fe7e8bf1641e48b3a460dd1232dc90d48a45 Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Fri, 24 Jul 2020 21:09:30 +0300 Subject: [PATCH] docfix #1566 --- context/context.go | 12 ++++++++++-- go.mod | 2 +- hero/binding.go | 10 +++++++--- mvc/controller.go | 6 +++++- 4 files changed, 23 insertions(+), 7 deletions(-) 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)