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

我有一个结构,我正在尝试使用验证器 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 main


import (

    "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


PIPIONE
浏览 125回答 1
1回答

精慕HU

您不需要解析验证器中的字段并为特殊类型制作自定义案例。相反,只需创建一个新类型,然后您就可以使用普通绑定。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"`}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go