Description
Undefined validation function 'required_if' on field 'Field'
https://godoc.org/github.com/go-playground/validator#hdr-Required_If
How to reproduce
package main
import (
"github.com/gin-gonic/gin"
)
type ListReq struct {
Id int64 `form:"id" binding:"required,gte=1"`
AppCode string `form:"appCode" binding:"required"`
BranchTag string `form:"branchTag" binding:"required_if=Id 1"`
}
func main() {
g := gin.Default()
g.GET("/list", func(c *gin.Context) {
var form ListReq
if err := c.ShouldBindQuery(&form); err != nil {
c.String(http.StatusOK, "error")
return
}
c.String(http.StatusOK, "ok")
})
g.Run(":9000")
}
Expectations
$ curl -i http://localhost:9000/list
ok
Actual result
$ curl -i http://localhost:9000/list
curl: (52) Empty reply from server
Undefined validation function 'required_if' on field 'BranchTag'
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/go-playground/validator/v10/cache.go:289 (0xd6ae36)
(*Validate).parseFieldTagsRecursive: panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, current.tag, fieldName)))
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/go-playground/validator/v10/cache.go:150 (0xd68e27)
(*Validate).extractStructCache: ctag, _ = v.parseFieldTagsRecursive(tag, fld.Name, "", false)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/go-playground/validator/v10/validator.go:37 (0xd71aed)
(*validate).validateStruct: cs = v.v.extractStructCache(current, typ.Name())
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/go-playground/validator/v10/validator_instance.go:304 (0xd7a02d)
(*Validate).StructCtx: vd.validateStruct(ctx, top, val, val.Type(), vd.ns[0:0], vd.actualNs[0:0], nil)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/go-playground/validator/v10/validator_instance.go:277 (0xd79ad6)
(*Validate).Struct: return v.StructCtx(context.Background(), s)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/binding/default_validator.go:30 (0xeebedd)
(*defaultValidator).ValidateStruct: if err := v.validate.Struct(obj); err != nil {
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/binding/binding.go:115 (0xeebd29)
validate: return Validator.ValidateStruct(obj)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/binding/query.go:20 (0xef2ca4)
queryBinding.Bind: return validate(obj)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:679 (0xf00c11)
(*Context).ShouldBindWith: return b.Bind(c.Request, obj)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:654 (0xf00785)
(*Context).ShouldBindQuery: return c.ShouldBindWith(obj, binding.Query)
I:/source/go/src/dev-zt-api.2345.cn/controller/webapi/appMobileController.go:186 (0x12af8c4)
CompList: if err := c.ShouldBindQuery(&form); err != nil {
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
(*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/middleware/user/user.go:45 (0x127f4d2)
User.func1: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
(*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/middleware/trace/traceLog.go:37 (0x12b6ae4)
LogBase.func1: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
(*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/middleware/cors/cors.go:29 (0x12b4cfa)
Cors.func1: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
(*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/logger.go:241 (0xf174f7)
LoggerWithConfig.func1: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
(*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/middleware/cors/recovery.go:107 (0x12b6684)
RecoveryWithWriter.func1: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/context.go:161 (0xefcb5b)
(*Context).Next: c.handlers[c.index](c)
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/gin.go:409 (0xf09ef2)
(*Engine).handleHTTPRequest: c.Next()
I:/source/go/src/dev-zt-api.2345.cn/vendor/github.com/gin-gonic/gin/gin.go:367 (0xf0997e)
(*Engine).ServeHTTP: engine.handleHTTPRequest(c)
C:/Go/src/net/http/server.go:2843 (0x9bf86a)
serverHandler.ServeHTTP: handler.ServeHTTP(rw, req)
C:/Go/src/net/http/server.go:1925 (0x9b9944)
(*conn).serve: serverHandler{c.server}.ServeHTTP(w, w.req)
C:/Go/src/runtime/asm_amd64.s:1374 (0x5f5c00)
goexit: BYTE $0x90 // NOP
<!-- Actual result showing the problem -->
Environment
- go version:1.5.2
- gin version (or commit ref):1.6.3
- operating system:win10 1909
Comment From: Doarakko
required_if
was released in v10.4.0, but because gin uses go-validator v10.2.0.
https://github.com/go-playground/validator/pull/658
https://github.com/go-playground/validator/releases/tag/v10.4.0
I created a PR to upgrade go-validator! https://github.com/gin-gonic/gin/pull/2536
Comment From: gspgsp
also want to know: 2022/08/24 11:32:31 http: panic serving 192.168.0.124:58997: Undefined validation function 'excluded_if' on field 'Mobile'