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

我正在使用来验证一些输入,并且在自定义验证标记和函数方面遇到了一些问题。问题是,当其中一个结构字段是另一个结构时,不会调用该函数。下面是一个示例:go-playground/validator/v10


type 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"


有人知道我做错了什么吗?


慕姐8265434
浏览 112回答 2
2回答

30秒到达战场

搜索了一段时间后,我终于找到了一个名为的函数,该函数注册了一个自定义类型,这将使验证它成为可能。因此,解决方案是将以下内容添加到问题中的示例中:RegisterCustomTypeFuncgo-playground/validator/v10func childStructCustomTypeFunc(field reflect.Value) interface{} {&nbsp; &nbsp;&nbsp; &nbsp; if value, ok := field.Interface().(ChildStruct); ok {&nbsp; &nbsp; &nbsp; &nbsp; return value.Value&nbsp; &nbsp; }&nbsp; &nbsp; return nil}䋰:validator.RegisterCustomTypeFunc(childStructCustomTypeFunc, ChildStruct{})现在验证器将进入函数,并且返回消息将是字段的错误myValidateParentStruct.Child

不负相思意

该函数正在注册字段级别的自定义验证程序,如已注册函数的类型所示。validator.RegisterValidation(...)func(fl validator.FieldLevel) bool结构字段本身不会以这种方式进行验证,并且您的自定义验证程序将被忽略。要验证结构字段,应使用 ,其中函数的类型为 。validate.RegisterStructValidation(myValidate, ChildStruct{})myValidatevalidator.StructLevelFunc在此函数中,您可以对结构、字段本身和/或其嵌套字段执行验证:func myValidate(sl validator.StructLevel) {&nbsp; &nbsp; fmt.Println("INSIDE MY VALIDATOR") // now called&nbsp; &nbsp; if sl.Current().Interface().(ChildStruct).Value != 20 {&nbsp; &nbsp; &nbsp; &nbsp; sl.ReportError(sl.Current().Interface(), "ChildStruct", "", "", "")&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; vald := validator.New()&nbsp; &nbsp; vald.RegisterStructValidation(myValidate, ChildStruct{})&nbsp; &nbsp; data := &ParentStruct{&nbsp; &nbsp; &nbsp; &nbsp; Child: ChildStruct{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Value: 10,&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; }&nbsp; &nbsp; validateErr := vald.Struct(data)&nbsp; &nbsp; if validateErr != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("GOT ERROR")&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(validateErr)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println("DONE")}操场上的例子:https://play.golang.org/p/f0f2YE_e1VL
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go