【问题标题】:how to validate a struct field of type null.v4 package with validator v10?如何使用验证器 v10 验证 null.v4 包类型的结构字段?
【发布时间】:2020-10-14 19:13:12
【问题描述】:

我有一个结构,我正在尝试使用验证器 v10 来验证一个结构,该结构的字段可以是 null.v4 包中的 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}

你会得到{ “数据”:1, “状态”:“好的” }

当我期待Error:Field validation for 'Foo' failed on the 'nullIntMin' tag

【问题讨论】:

    标签: validation go null go-gin


    【解决方案1】:

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

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

    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"`
    }
    

    【讨论】:

      猜你喜欢
      • 2021-07-20
      • 1970-01-01
      • 2020-09-10
      • 2012-03-13
      • 1970-01-01
      • 2018-09-08
      • 2021-05-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多