Custom validators for struct fields
- [x] I have looked at the documentation here first?
- [x] I have looked at the examples provided that may showcase my question here?
Package version eg. v9, v10:
v10
Issue, Question or Enhancement:
The documentation says that only required and omitempty can be used on struct-type fields. This makes some sense (most of the validators don't make sense on a struct, e.g. gt, alpha, etc.). However, it looks like custom validators don't get run, and they're treated as if they were required instead.
Code sample, to showcase or reproduce:
https://play.golang.org/p/ydSUIxEIE1k
package main
import (
"log"
"github.com/go-playground/validator/v10"
)
// User contains user information
type User struct {
FirstName string `validate:"required"`
LastName string `validate:"required"`
Mother *User `validate:"same-last-name"`
}
func main() {
validate := validator.New()
validate.RegisterValidation("same-last-name", func(fl validator.FieldLevel) bool {
log.Printf("validation called on %s", fl.StructFieldName())
return true
})
user := &User{
FirstName: "Badger",
LastName: "Smith",
Mother: &User{
FirstName: "Jane",
LastName: "Imposter",
},
}
log.Printf("validation results: %v", validate.Struct(user))
}
I expect this to log validation called on Mother and then successful validation; instead the validation fails (due to the nested User having a nil Mother) without the log message ever getting printed:
2009/11/10 23:00:00 validation results: Key: 'User.Mother.Mother' Error:Field validation for 'Mother' failed on the 'same-last-name' tag
Program exited.
If the structure is not recursive, the validation instead silently passes (again without actually calling the custom validator):
https://play.golang.org/p/XMirPpgbNFX
so this makes me think that the validator is being treated as if it were required.
I understand that it's possible to register a struct-level validator, but that's per-type and therefore can't be applied in cases like this where they need to be enabled for particular fields or with parameters.
hey, there, maybe you can try this against v10:
validate.RegisterValidation("same-last-name", func(fl validator.FieldLevel) bool {
log.Printf("validation called on %s", fl.StructFieldName())
return true
}, true)
It works for me.
➜ go run main.go
2021/09/03 20:00:25 validation called on Mother
2021/09/03 20:00:25 validation results: <nil>
As you can see the function signature, it has already be supported.
@quentinmit , have you solved your issue ?
Just ran into this issue while trying to add validation to a struct containing a shopspring/decimal.
I registered a custom field validator and expected that it would get called for the decimal field, where I could cast field.Interface(), forcibly cast it to the decimal, and perform my custom validation logic there.
Tested on v10.12.0.
Just ran into this issue while trying to add validation to a struct containing a shopspring/decimal.
I registered a custom field validator and expected that it would get called for the decimal field, where I could cast field.Interface(), forcibly cast it to the decimal, and perform my custom validation logic there.
Tested on v10.12.0.
Can you give an example of how you registered a custom field validator please?
I am facing similar problem. @quentinmit Did you get it working?