首页 > 解决方案 > 如何使用自定义验证器验证结构数据类型?

问题描述

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

如果我将 parentStruct 更改为:

type ParentStruct struct {
    Child int `validate:"myValidate"`
}

一切正常。但是,如果我将validate:"myValidate"部件添加到 ChildStruct 它也可以工作,那么返回的错误是说 ChildStruct.Value 是错误的,而它应该说 ParentStruct.Child 是错误的。

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

标签: gogo-playground

解决方案


经过一段时间的搜索,我终于找到了一个名为的函数RegisterCustomTypeFunc,它注册了一个自定义类型,可以对其go-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{})

现在验证器将进入myValidate函数,返回消息将是该ParentStruct.Child字段的错误


推荐阅读