mirror of
https://github.com/astaxie/beego.git
synced 2024-11-29 14:01:29 +00:00
add Recursively validation
This commit is contained in:
parent
c4aa33fb1b
commit
d0e7dd686b
@ -333,3 +333,42 @@ func (v *Validation) Valid(obj interface{}) (b bool, err error) {
|
|||||||
|
|
||||||
return !v.HasErrors(), nil
|
return !v.HasErrors(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recursively validate a struct.
|
||||||
|
// Step1: Validate by v.Valid
|
||||||
|
// Step2: If pass on step1, then reflect obj's fields
|
||||||
|
// Step3: Do the Recursively validation to all struct or struct pointer fields
|
||||||
|
// Anonymous fields will be ignored
|
||||||
|
func (v *Validation) RecursiveValid(objc interface{}) (bool, error) {
|
||||||
|
//Step 1: validate obj itself firstly
|
||||||
|
pass, err := v.Valid(objc)
|
||||||
|
if err != nil || false == pass {
|
||||||
|
return pass, err // Stop recursive validation
|
||||||
|
} else { //pass
|
||||||
|
// Step 2: Validate struct's struct fields
|
||||||
|
objT := reflect.TypeOf(objc)
|
||||||
|
objV := reflect.ValueOf(objc)
|
||||||
|
if isStruct(objT) || isStructPtr(objT) {
|
||||||
|
|
||||||
|
if isStructPtr(objT) {
|
||||||
|
objT = objT.Elem()
|
||||||
|
objV = objV.Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < objT.NumField(); i++ {
|
||||||
|
|
||||||
|
t := objT.Field(i).Type
|
||||||
|
|
||||||
|
if isStruct(t) || isStructPtr(t) {
|
||||||
|
// Step 3: do the recursive validation
|
||||||
|
// Only valid the Public field recursively
|
||||||
|
if objV.Field(i).CanInterface() {
|
||||||
|
pass, err = v.RecursiveValid(objV.Field(i).Interface())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pass, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -343,3 +343,33 @@ func TestValid(t *testing.T) {
|
|||||||
t.Errorf("Message key should be `Name.Match` but got %s", valid.Errors[0].Key)
|
t.Errorf("Message key should be `Name.Match` but got %s", valid.Errors[0].Key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRecursiveValid(t *testing.T) {
|
||||||
|
type User struct {
|
||||||
|
Id int
|
||||||
|
Name string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
|
||||||
|
Age int `valid:"Required;Range(1, 140)"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AnonymouseUser struct {
|
||||||
|
Id2 int
|
||||||
|
Name2 string `valid:"Required;Match(/^(test)?\\w*@(/test/);com$/)"`
|
||||||
|
Age2 int `valid:"Required;Range(1, 140)"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Account struct {
|
||||||
|
Password string `valid:"Required"`
|
||||||
|
U User
|
||||||
|
AnonymouseUser
|
||||||
|
}
|
||||||
|
valid := Validation{}
|
||||||
|
|
||||||
|
u := Account{Password: "abc123_", U: User{}}
|
||||||
|
b, err := valid.RecursiveValid(u)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if b {
|
||||||
|
t.Error("validation should not be passed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user