Beego valid包校验失效主因是结构体字段未导出或valid标签缺失/拼写错误;JSON需手动json.Unmarshal后校验;自定义规则须用AddRule注册;GET参数类型转换需手动处理。

Beego 中 valid 包校验失效的常见原因
直接在 Controller 里调用 valid.Valid 却没报错、也没拦截非法参数?大概率是没正确绑定结构体字段标签,或漏了 valid:"..." 声明。Beego 的校验不依赖请求方法(GET/POST),但必须确保结构体字段有 valid 标签,且字段可导出(首字母大写)。
- 字段未导出 →
valid包完全跳过该字段,不报错也不校验 - 标签写成
validation:"required"或validate:"required"→ Beego 只认valid这个 key - 结构体嵌套但没加
valid:"required"到嵌套字段上 → 外层字段非空不代表内层自动校验 - 使用
c.ParseForm(&v)后才校验 → 正确,但若先调c.Input().Get("xxx")手动取值,校验就失去意义
POST 接口用 valid 校验 JSON 请求体的写法
Beego 默认不自动解析 JSON body 到结构体,需手动调用 json.Unmarshal,再交给 valid 包。别指望 c.ParseForm 能处理 JSON —— 它只读 application/x-www-form-urlencoded 和 multipart/form-data。
- 先定义结构体,字段带
valid标签:type CreateUserReq struct { Name string `json:"name" valid:"Required;MinSize(2);MaxSize(20)"` Age int `json:"age" valid:"Required;Range(0,150)"` Email string `json:"email" valid:"Required;Email"` } - 在 Controller 方法中解析并校验:
var req CreateUserReq if err := json.Unmarshal(c.Ctx.Input.RequestBody, &req); err != nil { c.Data["json"] = map[string]interface{}{"error": "invalid json"} c.ServeJSON() return } valid := validation.Validation{} if b, _ := valid.Valid(&req); !b { c.Data["json"] = map[string]interface{}{"error": valid.Errors[0].Message} c.ServeJSON() return } - 注意:
valid.Errors是切片,第一个错误不等于“最严重”的错误,只是校验顺序触发的第一个
valid 支持的内置规则和自定义规则扩展方式
Beego valid 包自带常用规则,但像手机号、身份证、URL 必须自己注册函数。规则名区分大小写,且不能含括号以外的符号(如 phone() 合法,is_phone() 会 panic)。
- 常用内置规则:
Required、MinSize(n)、MaxSize(n)、Range(min,max)、Email、Alpha、AlphaNumeric - 添加自定义规则(例如校验 11 位手机号):
func isMobile(v interface{}) bool { s, ok := v.(string) if !ok { return false } return regexp.MustCompile(`^1[3-9]\d{9}$`).MatchString(s) } validation.AddRule("Mobile", isMobile)之后就能在结构体中写valid:"Mobile" - 自定义规则函数返回
bool,不抛异常;错误信息需靠valid.SetError或在调用处手动拼接
GET 接口参数校验容易忽略的兼容性细节
GET 请求参数走 URL query string,c.Input().Get("xxx") 返回的是字符串,而结构体字段可能是 int 或 bool。Beego 不会自动类型转换,valid 对非字符串字段校验前会尝试转类型,失败则直接判定为不满足 Required(即使 query 里传了 id=123,但结构体字段是 int64,而 query 值是字符串,valid 内部转换失败就会报错)。
- 安全做法:对 GET 参数,先用
c.Input().Get取出字符串,再手动strconv.Atoi等转换,捕获错误后提前返回 - 如果坚持用结构体 +
valid,字段类型必须全为string,或自行实现UnmarshalText方法支持字符串转目标类型 -
valid:"Required"对空字符串""有效,但对缺失参数(c.Input().Get("x") == "")也生效 —— 这点和 POST JSON 不同,JSON 缺失字段可能被设为零值而非空字符串
valid 包轻量但不够智能,它不处理深层嵌套校验、不支持条件校验(比如 “当 type=admin 时,password 必填”),这类逻辑得写在业务代码里判断。真正上线前,务必用空值、超长字符串、非法邮箱等组合 case 跑一遍接口,光看文档里的例子容易漏掉 tag 拼写或类型转换问题。











