2

我正在尝试使用 gin 框架创建验证器/绑定器中间件。

这是模型

type LoginForm struct{
    Email string `json:"email" form:"email" binding:"email,required"`
    Password string `json:"password" form:"password" binding:"required"`
}

路由器

router.POST("/login",middlewares.Validator(LoginForm{}) ,controllers.Login)

中间件

func Validator(v interface{}) gin.HandlerFunc{
    return func(c *gin.Context){
        a := reflect.New(reflect.TypeOf(v))
        err:=c.Bind(&a)
        if(err!=nil){
            respondWithError(401, "Login Error", c)
            return
        }
        c.Set("LoginForm",a)
        c.Next()
    }
}

我对golang很陌生。我知道问题在于绑定到错误的变量。有没有其他方法可以解决这个问题?

4

1 回答 1

0

澄清我的评论,

func Validator(v interface{}) gin.HandlerFunc不要使用 MW的签名,而是使用func Validator(f Viewfactory) gin.HandlerFunc

如果ViewFactory函数类型如type ViewFactory func() interface{}

MW可以改变,所以

type ViewFactory func() interface{}

func Validator(f ViewFactory) gin.HandlerFunc{
    return func(c *gin.Context){
        a := f()
        err:=c.Bind(a) // I don t think you need to send by ref here, to check by yourself
        if(err!=nil){
            respondWithError(401, "Login Error", c)
            return
        }
        c.Set("LoginForm",a)
        c.Next()
    }
}

你可以这样写路由器

type LoginForm struct{
    Email string `json:"email" form:"email" binding:"email,required"`
    Password string `json:"password" form:"password" binding:"required"`
}
func NewLoginForm() interface{} {
   return &LoginForm{}
}
router.POST("/login",middlewares.Validator(NewLoginForm) ,controllers.Login)

更进一步,我认为您可能需要稍后再了解这一点,一旦您有了interface{}价值,您就可以将其恢复为LoginForm这样v := some.(*LoginForm)

或者像这样以获得更高的安全性

if v, ok := some.(*LoginForm); ok {
 // v is a *LoginForm
}

有关更深入的信息,请参阅 golang 类型断言。

于 2016-10-31T19:37:29.113 回答