使用ozzo-validation时嵌入结构体的Validate方法未被调用
问题解决:ozzo-validation嵌套结构体验证不触发父结构体Validate方法
问题原因
ozzo-validation不会自动递归验证嵌入的结构体,即使嵌入的结构体实现了Validate方法,也需要在子结构体的验证逻辑中显式触发父结构体的验证。
修复方案
方案1:显式调用父结构体的Validate方法
修改MyOtherStruct的Validate方法,先触发嵌入的MyStruct验证,再处理自身字段验证,最后合并错误:
func (m MyOtherStruct) Validate() error { fmt.Println("calling MyOtherStruct validator") // 先执行MyStruct的验证逻辑 if err := m.MyStruct.Validate(); err != nil { return err } // 验证自身字段 err := validation.ValidateStruct( &m, validation.Field(&m.PersonnelID, validation.Match(personnelIDRegexp)), validation.Field(&m.City, validation.Required), validation.Field(&m.Comment), validation.Field(&m.FirstDate, validation.Date(time.DateOnly)), validation.Field(&m.SecondDate, validation.Date(time.DateOnly)), ) return err }
注:原代码中ValidateStruct缺少结构体实例指针参数(需补充&m);同时MyStruct的Validate方法里的uui是未定义变量,需替换为接收者m,比如&m.UUID,否则会编译报错。
方案2:通过validation.Valid()规则触发验证
在MyOtherStruct的ValidateStruct中,将嵌入的MyStruct作为字段添加validation.Valid()规则,自动触发其Validate方法:
func (m MyOtherStruct) Validate() error { fmt.Println("calling MyOtherStruct validator") err := validation.ValidateStruct( &m, // 触发MyStruct的验证 validation.Field(&m.MyStruct, validation.Valid()), validation.Field(&m.PersonnelID, validation.Match(personnelIDRegexp)), validation.Field(&m.City, validation.Required), validation.Field(&m.Comment), validation.Field(&m.FirstDate, validation.Date(time.DateOnly)), validation.Field(&m.SecondDate, validation.Date(time.DateOnly)), ) return err }
这种方式更贴合ozzo-validation的字段验证风格,会自动合并父结构体与子结构体的验证错误。
额外修正:原代码变量错误
MyStruct的Validate方法中使用了未定义的uui变量,需替换为接收者m:
func (m MyStruct) Validate() error { fmt.Println("calling MyStruct validator") err := validation.ValidateStruct( &m, validation.Field(&m.UUID, is.UUID), validation.Field(&m.FirstUUID, validation.Required, is.UUID), validation.Field(&m.SecondUUID, validation.Required, is.UUID), validation.Field(&m.ThirdUUID, validation.Required, is.UUID), validation.Field(&m.Email, validation.Required, is.Email), validation.Field(&m.PhoneNumber, validation.Required, validation.Match(mobileRegexp)), validation.Field(&m.SkypeID, validation.Required), ) return err }
内容的提问来源于stack exchange,提问作者Zeinab Abbasimazar
相关产品推荐
相关产品推荐

