为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用验证器 v10 验证 null.v4 包类型的结构字段?

如何使用验证器 v10 验证 null.v4 包类型的结构字段?

Go
PIPIONE 2022-07-11 10:40:09
我有一个结构,我正在尝试使用验证器 v10 验证一个结构,该结构的字段可以是 null.XX 包中的 null.XX 类型。type FooStruct struct {    Foo null.Int `json:"foo" binding:"nullIntMin=1"`}它(显然)不是开箱即用的,所以我正在尝试制作一个自定义验证器。var validateNullIntMin validator.Func = func(fl validator.FieldLevel) bool {    number, ok := fl.Field().Interface().(null.Int)    min := cToInt(fl.Param())    if ok {        if number.Value > min && number.Valid {            return false        }    }    return true}func cToInt(param string) int64 {    i, err := strconv.ParseInt(param, 0, 64)    panic(err)    return i}问题是数据从未经过验证。甚至从未进入该功能,我不明白为什么。重现示例:package mainimport (    "log"    "net/http"    "strconv"    "github.com/gin-gonic/gin"    "github.com/gin-gonic/gin/binding"    "github.com/go-playground/validator"    "gopkg.in/guregu/null.v4")type FooStruct struct {    Foo null.Int `json:"foo" binding:"nullIntMin=3"`}var validateNullIntMin validator.Func = func(fl validator.FieldLevel) bool {    log.Println("inside validator")    number, ok := fl.Field().Interface().(null.Int)    min := cToInt(fl.Param())    if ok {        if number.Valid && number.Int64 > min {            return false        }    }    return true}func cToInt(param string) int64 {    i, err := strconv.ParseInt(param, 0, 64)    panic(err)    return i}func main() {    route := gin.Default()    // Custom validator    if v, ok := binding.Validator.Engine().(*validator.Validate); ok {        v.RegisterValidation("nullIntMin", validateNullIntMin)    }    route.POST("/foo", postFoo)    route.Run(":5000")}func postFoo(c *gin.Context) {    var f FooStruct    err := c.BindJSON(&f)    if err != nil {        c.JSON(http.StatusBadRequest, gin.H{"status": http.StatusText(http.StatusBadRequest)})        return    }    c.JSON(http.StatusOK, gin.H{"status": http.StatusText(http.StatusOK), "data": f.Foo.Int64})}如果你用{"foo":1}你会得到 { "data": 1, "status": "OK" }当我期待Error:Field validation for 'Foo' failed on the 'nullIntMin' tag
查看完整描述

1 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

您不需要解析验证器中的字段并为特殊类型制作自定义案例。


相反,只需创建一个新类型,然后您就可以使用普通绑定。


if v, ok := binding.Validator.Engine().(*validator.Validate); ok {

    v.RegisterCustomTypeFunc(nullIntValidator, null.Int{})

}


func nullIntValidator(field reflect.Value) interface{} {

    if valuer, ok := field.Interface().(null.Int); ok {

        if valuer.Valid {

            return valuer.Int64

        }

    }

    return nil

}

type FooStruct struct {

    Foo  null.Int  `json:"foo" binding:"min=3"`

}


查看完整回答
反对 回复 2022-07-11
  • 1 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信