beego validation.register不生效的典型表现是结构体字段加valid:"myrule"后校验未触发且haserrors()返回false,主因是注册时机错误(须在parseform前)、函数名大小写不匹配、未绑定到实际validation实例,或跨字段校验误用register而非valid接口。

beego validation.Register方法不生效的典型表现
调用了 validation.Register,但结构体字段加了 valid:"myrule" 后完全没触发校验函数——HasErrors() 返回 false,错误列表为空。最常见原因是注册时机错、函数名不匹配或未绑定到实际使用的 Validation 实例。
必须在 ParseForm 之前完成注册
Beego 的 validation 模块不是全局单例,每次 new 一个 validation.Validation 都是独立实例。自定义规则只对注册到该实例的规则生效。所以不能写成:
// ❌ 错误:在 init() 或任意非请求上下文中注册
func init() {
validation.Register("chinese_mobile", chineseMobileRule)
}
而应在每次需要校验的请求中、调用 c.ParseForm() 或手动构造 Validation 实例前注册:
- 若用结构体 +
ParseForm方式,注册必须放在c.ParseForm(&user)之前 - 若用
GetString+ 手动valid.Required(...)方式,注册必须在valid := validation.Validation{}之后、首次调用valid.Xxx()之前 - 注册一次即可,重复注册会 panic,可用
validation.IsRegistered("myrule")防御
StructTag 中 valid 规则名大小写必须严格一致
结构体字段的 valid tag 值和 Register 第一个参数必须完全相等(包括大小写、下划线):
type User struct {
Mobile string `valid:"chinese_mobile"` // 注意这里是下划线
}
// ✅ 正确注册
validation.Register("chinese_mobile", chineseMobileRule)
// ❌ 不生效:大小写或符号不一致
validation.Register("ChineseMobile", ...) // 不匹配
validation.Register("chineseMobile", ...) // 不匹配
validation.Register("chinese-mobile", ...) // 不匹配
另外,valid tag 内多个规则用分号 ; 分隔,空格可选,但括号和引号必须闭合;正则表达式需用 /.../ 包裹,如 Match(/^1[3-9]\d{9}$/)。
跨字段校验只能靠 Valid() 方法,不能依赖 Register
比如要校验 Password 和 ConfirmPassword 是否一致,Register 注册的函数接收的是单个字段值,拿不到结构体其他字段。这时候必须让结构体实现 validation.ValidFormer 接口:
func (u *User) Valid(v *validation.Validation) {
if u.Password != u.ConfirmPassword {
v.SetError("ConfirmPassword", "两次输入密码不一致")
}
}
注意:Valid() 方法会在所有 StructTag 规则校验通过后才被调用;如果 StructTag 校验已失败(如 Required 不通过),Valid() 不会执行。
真正容易被忽略的是:StructTag 规则和 Valid() 是两套机制,前者是字段级、后者是结构体级;注册自定义规则只是扩展前者的能力,解决不了字段间逻辑耦合问题。











