parseform 必须传 ¬e{}(值类型地址),不可传 &(¬e{});结构体字段需导出且带匹配 form 标签;出错时部分字段可能已赋值,须检查 err 并校验关键字段;xsrf 开启时需提交 _xsrf 值。

ParseForm 传参必须是 &struct{},不是 &(&struct{})
Beego 的 ParseForm 方法内部依赖反射遍历结构体字段并赋值,它要求传入的参数是「可寻址的结构体变量地址」。常见错误是先声明指针再取地址:n := &Note{},然后调用 this.ParseForm(&n) —— 这实际传的是 **Note,反射找不到目标字段,导致 n.Title 为空或打印出类似 %!s(*string=0xc82027a368) 的内存地址。
✅ 正确做法只有这一种:
- 用值类型初始化:
n := Note{} - 传其地址:
this.ParseForm(&n) - 后续直接访问字段:
n.Title,不要写&n.Title
结构体字段必须导出且带 form 标签
Go 的反射无法访问非导出(小写首字母)字段,ParseForm 会直接跳过它们。同时,字段必须通过 form tag 显式声明映射关系,否则不绑定。
例如 HTML 中有 <input name="title">,对应结构体必须写成:
type Note struct {
Id int `form:"-"`
Title string `form:"title"`
Body string `form:"body"`
}
注意:
-
Id字段加form:"-"表示忽略,不会尝试解析 -
title和body必须与 HTML 中name属性完全一致(区分大小写) - 如果字段名本身就是
Title,但表单字段叫post_title,就得写`form:"post_title"`
ParseForm 返回 err 时字段可能部分填充
ParseForm 不是原子操作:某个字段类型不匹配(比如前端传 "abc" 到 int 字段),它会返回 error,但之前成功解析的字段值仍保留在结构体中。这容易造成脏数据误用。
务必检查 err:
- 不要忽略
err != nil分支 - 出错时建议清空或拒绝使用该结构体实例
- 对关键字段(如 ID、金额)做二次校验,别只信 ParseForm 的结果
XSRF 开启时表单必须携带 xsrfdata
如果项目启用了 XSRF 保护(默认开启),而 HTML 表单没嵌入 {{.xsrfdata}},ParseForm 会直接返回 403 Forbidden 错误,且不解析任何字段。
确保模板中类似这样:
另外确认路由已注册为 POST 方法,且控制器方法签名是 func (c *HelloController) Post(),不是 Get() 或其他。
最易被忽略的点是:结构体初始化方式和字段导出性——这两项任一出错,ParseForm 都静默失败,既不报错也不赋值,只能靠日志或调试器发现字段为空。别假设“写了 struct 就一定被填”。











