我正在将表单数据传递给 Go 中的控制器。我已验证数据是否已到达控制器,因为其值出现在这些变量中:
emailValue := c.PostForm("email");
passwordValue := c.PostForm("password");
Run Code Online (Sandbox Code Playgroud)
然而,我正在开发一个样板项目来尝试自学 Go,并且我对其中包含的一些进一步处理感到困惑。“无效的登录表单”错误总是在以下函数中触发:
func (ctrl UserController) Signin(c *gin.Context) {
var signinForm forms.SigninForm
if c.BindJSON(&signinForm) != nil {
c.JSON(406, gin.H{"message": "Invalid signin form", "form": signinForm})
c.Abort()
return
}
user, err := userModel.Signin(signinForm)
if err == nil {
session := sessions.Default(c)
session.Set("user_id", user.ID)
session.Set("user_email", user.Email)
session.Set("user_name", user.Name)
session.Save()
c.JSON(200, gin.H{"message": "User signed in", "user": user})
} else {
c.JSON(406, gin.H{"message": "Invalid signin details", "error": err.Error()})
}
}
Run Code Online (Sandbox Code Playgroud)
通过阅读文档和其他 Stack Overflow 问题,我无法弄清楚 BindJSON 在这种情况下到底在做什么。struct这是文件中的相关内容forms:
type SigninForm struct {
Email string `form:"email" json:"email" binding:"required,email"`
Password string `form:"password" json:"password" binding:"required"`
}
Run Code Online (Sandbox Code Playgroud)
我正在做什么BindJSON以及如何确保这一点c.BindJSON(&signinForm) == nil?
我在这里可能会产生误解,但是如果您的内容可以在PostForm通话中使用,那么我会假设Content-Type不是application/json但可能是application/x-www-form-urlencoded。如果是这种情况,则 usingBindJSON将不起作用,因为它试图将 post 数据绑定到通过将 post 数据解析为 json 定义的结构。我认为这可能有效:
if err := c.ShouldBindWith(&signinForm, binding.Form); err != nil {
c.JSON(406, gin.H{"message": "Invalid signin form", "form": signinForm})
c.Abort()
return
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是将您的帖子数据实际以 json 形式发送,类似于:
{"email": "test@example.com", "password": "pass"}
Run Code Online (Sandbox Code Playgroud)
并确保Content-Type标题是application/json
我从来没有用过杜松子酒,所以这可能是完全错误的。