本文是对 validate tag not
working in ShouldBindWith 的回答。
有人提了这么一个问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package main
import ( "log" "net/http"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" )
type MyStruct struct { Order string `form:"order,default=DESC" validate:"omitempty,oneof=ASC DESC"` }
func startPage(c *gin.Context) { var person MyStruct if c.ShouldBindWith(&person, binding.Query) == nil { log.Println("====== Only Bind By Query String ======") log.Println(person.Order) c.String(http.StatusOK, "Success") return } c.String(http.StatusBadRequest, "Failed") return }
func main() {
route := gin.Default() route.Any("/testing", startPage) route.Run(":8085") }
|
然后表单验证的时候,明明 Order 传递了一个不符合
oneof=ASC DESC
的值,但却验证通过了。
原因
虽然 gin 使用了 go-playground/validator
来作为表单验证的组件,但是在 gin 里面却修改了 struct 验证的
tagname,我们可以看看 default_validator.go#L95
1 2 3 4 5 6
| func (v *defaultValidator) lazyinit() { v.once.Do(func() { v.validate = validator.New() v.validate.SetTagName("binding") }) }
|
然后,我们就不能通过给 struct 加上 vaidate
的 tag
来写上我们的验证规则,取而代之的是,需要将我们的验证规则写在
binding
这个 tag 里面:
将 validate:"omitempty,oneof=ASC DESC"
替换成
binding:"omitempty,oneof=ASC DESC"
,我们即可实现在 gin
中使用 validator 验证我们的 struct。
1 2 3
| type MyStruct struct { Order string `form:"order,default=DESC" binding:"omitempty,oneof=ASC DESC"` }
|
参考官方文档: 模型绑定和验证