Revel 不自动绑定表单字段,需显式调用 c.Params.Bind 或依赖控制器参数绑定;控制器参数绑定要求字段名与参数名严格一致、类型简单、无嵌套;结构体字段必须导出,嵌套用点号命名,切片用 [] 后缀;PUT 请求需先调用 ParseForm()。

c.Params.Bind 不是默认行为,Revel 不会自动把表单字段映射到结构体字段——必须显式调用或使用控制器参数绑定机制。
控制器方法参数直接绑定(最简场景)
当表单字段名与控制器参数名完全一致时,Revel 会在方法执行前自动尝试转换并填充。这适用于已知字段名、类型简单、无嵌套的场景。
- 表单需提交
application/x-www-form-urlencoded或multipart/form-data,且字段名如name、age、active - 控制器方法签名必须与字段名严格匹配(区分大小写),例如:
func (c AppController) Save(name string, age int, active bool) revel.Result - 不支持嵌套结构体自动展开,
user.Name这类点号命名不会被识别;若要绑定User结构体,得手动解析或改用c.Params.Bind - 缺失字段时参数取零值(
""、0、false),不会报错,校验需自行补充
c.Params.Bind 绑定结构体切片(动态字段核心解法)
处理多个同名字段(如 answers[]=a&answers[]=b&answers[]=c)时,c.Params.Get("answers") 只返回第一个值,必须用 c.Params.Bind 或底层 c.Request.Form。
-
c.Params.Bind支持切片语法:c.Params.Bind(&answers, "answers[]"),其中answers是[]string或自定义结构体切片 - 结构体字段必须导出(首字母大写),否则绑定失败且静默忽略;例如
type Answer struct { Text string }可绑,text string不行 - 若前端用有序索引(
answers[0]=a&answers[1]=b),Bind会生成稀疏切片([]string{"a","b"}),但answers[2]缺失时对应位置为零值 - 对
[]Answer,推荐配合c.Request.Form["answers"]手动遍历构建,更可控、易调试
嵌套结构体绑定要注意字段导出与命名规范
Revel 使用反射访问结构体字段,所有参与绑定的字段(含嵌套层级)都必须导出,且 name 属性需符合框架解析规则。
- HTML 表单中嵌套字段应使用点号命名,例如:
、 - 对应 Go 结构体必须导出:
type User struct { Name string; Email string },不能是name string - 切片字段需用
[]后缀,如user.Hobbies[]=reading&user.Hobbies[]=coding→User{Hobbies: []string{"reading","coding"}} - 时间字段需匹配内置格式(
"2006-01-02"等)或提前注册到revel.TimeFormats,否则绑定为零值
真正容易被忽略的是:Revel 的 c.Params.Form 默认为空,尤其在 PUT 请求里,即使 Content-Type 正确也不会自动填充;必须先调用 c.Request.ParseForm() 或 c.Request.ParseMultipartForm(),否则 c.Request.Form 和 c.Params.Values 都拿不到数据。











