Buffalo表单验证需手动串联绑定、校验、错误注入与模板渲染四环节:c.Bind仅支持form-encoded/multipart,JSON会静默失败;结构体字段须大写+form标签;验证后须c.Set传递数据至模板;错误用{{.FormErrors.name}}渲染;唯一性等业务规则需DB层兜底;启用PrecompileTemplates可提前发现模板字段拼写错误。

Buffalo 的表单验证不是“开箱即用”的全自动流程,它依赖你显式控制绑定、校验、错误注入和模板渲染四个环节。漏掉任一环,就会出现字段为空、错误不显示、重提交清空表单等问题。
c.Bind 只认 form-encoded 和 multipart,JSON 会静默失败
前端发 application/json,c.Bind(&u) 不报错但结构体字段全为零值——这是最常被误判为“代码没生效”的原因。
- 确保 HTML 表单的
enctype是application/x-www-form-urlencoded(默认)或multipart/form-data(含文件时) - 结构体字段必须首字母大写 +
form:"name"标签,例如:Name string `form:"name"` -
<input name="name">的name值必须和form:标签值完全一致,大小写敏感 - 别用
json:标签混搭——c.Bind忽略它,schema.Decode忽略form:
验证失败后表单重渲染,必须手动塞结构体进 context
直接调 r.HTML("new.html") 不会保留用户刚填的数据,因为 POST body 已被读取一次,且 Buffalo 不自动重建上下文。
Buffalo框架 1.0.1 版本源码包下载,适合需要错误处理改进、依赖更新、render.Download 注释和 request logger 调整的 v1 项目。
- 先执行
c.Bind(&u),再立刻调c.Set("user", &u) - 模板中用
{{.user.Name}}取值,不是{{.FormValue "name"}}(后者在重渲染时已不可用) - 错误信息靠
{{.FormErrors.name}}渲染,Buffalo 在validate.Validate(&u)后自动注入该 map - 忘了
c.Set,用户就得重填全部字段——这不是 UI 问题,是上下文断链
validate 包只做内存校验,数据库约束得自己兜底
validate.Validate(&u) 通过 ≠ 数据能入库。比如邮箱重复、用户名已被占用,validate 完全不感知,pop.Create 才会因 PostgreSQL 的 UNIQUE 约束报错:
- 典型错误:
ERROR: duplicate key value violates unique constraint "users_email_key" - 解决办法:在
validate之后加 DB 查询,例如tx.Where("email = ?", u.Email).First(&existing) - 或捕获
pop.Error,用strings.Contains(err.Error(), "duplicate key")做分支处理 - 别把唯一性、关联存在性等业务规则全堆在 struct tag 里——
valid:"unique"并不存在
模板字段拼错要等运行时才 panic,提前发现靠 PrecompileTemplates
{{.user.Phone}} 写成 {{.user.phone}} 或结构体根本没 Phone 字段,Buffalo 不会在编译时报错,而是在用户访问页面时 panic。
- 在
app.go的App()函数里启用:app.PrecompileTemplates() - 启动
buffalo dev时就会扫描所有templates/文件,提前报出类似:template: "users/new.html":12:7: unknown field "phone" in struct - 这个检查只对
r.HTML()生效,r.JSON()或自定义响应不触发 - 配合 IDE 自动补全和
go vet,能避开大部分低级拼写错误
最容易被忽略的是:Buffalo 从不自动帮你做“绑定 → 校验 → 错误收集 → 上下文传递 → 模板渲染”这一整条链。每个环节都得你亲手串起来,少一步,用户就卡在白表单上。

















