2016-10-31 7 views
0

ginフレームワークを使用してバリデータ/バインダミドルウェアを作成しようとしています。golangのインタフェースから型変数を作成する

このモデル

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に非常に新しいです。私は問題が間違った変数へのバインディングであることを理解しています。 これを解決する他の方法はありますか?

+1

モデル変数ではなく、ファクトリで渡します。 'type ViewFactory func()interface {}' –

+0

私は分かりませんでした。あなたはもっと説明してください、または読むためのリンクを教えてくださいできますか? –

答えて

0

ようtype ViewFactory func() interface{}

としての機能タイプはMWが

ように変更することができる場合 func Validator(f Viewfactory) gin.HandlerFunc

ViewFactoryを使用し、代わりに、MWに対する署名func Validator(v interface{}) gin.HandlerFuncを有する

私のコメントを明確に

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() 
    } 
} 

このようなルータを書くことができます

012さらに行く
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{}値を持ったら、あなたはこのv := some.(*LoginForm)ようLoginFormそれをバックさせることができ、後でこれについて調べるために持っているかもしれないと思います。

よりセキュリティ

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

ため

またはこのような奥行き情報でより多くのためのgolangタイプのアサーションを参照してください。

+0

これは完全に機能します。私はもう1つの方法を見つけました。変更: a:= reflect.New(reflect.TypeOf(v)) err:= c.Bind(&a) a:= reflect.New(reflect.TypeOf(v))。 err:= c.Bind(a) –

+0

これは、前に紹介したような単純なケースでのみ機能します。私は、スライス、マップ、chans、または構造体ポインタに遭遇すると、状況がより複雑になると強く思っています。 –

関連する問題