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

如何使用自定义验证器验证结构数据类型?

如何使用自定义验证器验证结构数据类型?

Go
慕姐8265434 2022-08-24 20:09:44
我正在使用来验证一些输入,并且在自定义验证标记和函数方面遇到了一些问题。问题是,当其中一个结构字段是另一个结构时,不会调用该函数。下面是一个示例:go-playground/validator/v10type ChildStruct struct {    Value int}type ParentStruct struct {    Child ChildStruct `validate:"myValidate"`}func myValidate(fl validator.FieldLevel) bool {    fmt.Println("INSIDE MY VALIDATOR") // <- This is never printed    return false}func main() {    validator := validator.New()    validator.RegisterValidation("myValidate", myValidate)    data := &ParentStruct{        Child: ChildStruct{            Value: 10,        },    }    validateErr := validator.Struct(data)    if validateErr != nil { // <- This is always nil since MyValidate is never called        fmt.Println("GOT ERROR")        fmt.Println(validateErr)    }    fmt.Println("DONE")}如果我将父结构更改为:type ParentStruct struct {    Child int `validate:"myValidate"`}一切都很好。但是,如果我将部件添加到 ChildStruct 中,它也可以正常工作,则返回的错误是说 ChildStruct.Value 是错误的,而它应该说 ParentStruct.Child 是错误的。validate:"myValidate"有人知道我做错了什么吗?
查看完整描述

2 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

搜索了一段时间后,我终于找到了一个名为的函数,该函数注册了一个自定义类型,这将使验证它成为可能。因此,解决方案是将以下内容添加到问题中的示例中:RegisterCustomTypeFuncgo-playground/validator/v10


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

    if value, ok := field.Interface().(ChildStruct); ok {

        return value.Value

    }

    return nil

}

䋰:


validator.RegisterCustomTypeFunc(childStructCustomTypeFunc, ChildStruct{})

现在验证器将进入函数,并且返回消息将是字段的错误myValidateParentStruct.Child


查看完整回答
反对 回复 2022-08-24
?
不负相思意

TA贡献1777条经验 获得超10个赞

该函数正在注册字段级别的自定义验证程序,如已注册函数的类型所示。validator.RegisterValidation(...)func(fl validator.FieldLevel) bool


结构字段本身不会以这种方式进行验证,并且您的自定义验证程序将被忽略。


要验证结构字段,应使用 ,其中函数的类型为 。validate.RegisterStructValidation(myValidate, ChildStruct{})myValidatevalidator.StructLevelFunc


在此函数中,您可以对结构、字段本身和/或其嵌套字段执行验证:


func myValidate(sl validator.StructLevel) {

    fmt.Println("INSIDE MY VALIDATOR") // now called

    if sl.Current().Interface().(ChildStruct).Value != 20 {

        sl.ReportError(sl.Current().Interface(), "ChildStruct", "", "", "")

    }

}


func main() {

    vald := validator.New()

    vald.RegisterStructValidation(myValidate, ChildStruct{})

    data := &ParentStruct{

        Child: ChildStruct{

            Value: 10,

        },

    }

    validateErr := vald.Struct(data)

    if validateErr != nil {         

        fmt.Println("GOT ERROR")

        fmt.Println(validateErr)

    }

    fmt.Println("DONE")

}

操场上的例子:https://play.golang.org/p/f0f2YE_e1VL


查看完整回答
反对 回复 2022-08-24
  • 2 回答
  • 0 关注
  • 111 浏览
慕课专栏
更多

添加回答

举报

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