2009-10-21 25 views
5

実際には、WebServiceを使用して一部のクライアント情報を取得するアプリケーションがあります。 は、だから私は次のように私のActionResult内のログイン情報を検証しました:ASP.NET MVC - POSTデータを検証するActionFilterAttribute

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult ClientLogin(FormCollection collection) 
{ 
    if(Client.validate(collection["username"], collection["password"])) 
    { 
     Session["username"] = collection["username"]; 
     Session["password"] = collection["password"]; 
     return View("valid"); 
    } 
    else 
    { 
     Session["username"] = ""; 
     Session["password"] = ""; 
     return View("invalid"); 
    } 
} 
Client.Validate()はPOSTのユーザー名とパスワード

しかし、私に提供された情報に基づいてブール値を返すメソッドです

私の心が変わったので、メソッドの冒頭でその素敵なActionFilterAttributesを使いたいので、Client.validate()がtrueを返すだけで、[Authorize]と同じですがカスタムWebサービスであればレンダリングされます

[AcceptVerbs(HttpVerbs.Post)] 
[ValidateAsClient(username=postedUsername,password=postedPassword)] 
//Pass Posted username and password to ValidateAsClient Class 
//If returns true render the view 
public ActionResult ClientLogin() 
{ 
    return View('valid') 
} 

その後、ValidateAsClientの内側に私のようなものだろう。だから、私の問題がある

public class ValidateAsClient : ActionFilterAttribute 
{ 
    public string username { get; set; } 
    public string password { get; set; } 

    public Boolean ValidateAsClient() 
    { 
     return Client.validate(username,password); 
    } 
} 

を私はに投稿された情報を渡す方法がわからないので、私は、それを動作させるために、正確に方法がわかりません[ValidateAsClient(username = postedUsername、passwords = postedPassword)]また、ValidateAsClient関数を正しく動作させるにはどうすればよいですか?

私は、これはあなたが次のメソッドをオーバーライドする必要があり、事前

答えて

7

おそらくこのような何か:

[AttributeUsage(AttributeTargets.All)] 
public sealed class ValidateAsClientAttribute : ActionFilterAttribute 
{ 
    private readonly NameValueCollection formData; 
    public NameValueCollection FormData{ get { return formData; } } 

    public ValidateAsClientAttribute (NameValueCollection formData) 
    { 
     this.formData = formData; 
    } 

    public override void OnActionExecuting 
       (ActionExecutingContext filterContext) 
    { 
     string username = formData["username"]; 
     if (string.IsNullOrEmpty(username)) 
     { 
      filterContext.Controller.ViewData.ModelState.AddModelError("username"); 
     } 
     // you get the idea 
    } 
} 

そして、このようにそれを使用します。

[ValidateAsClient(HttpContext.Request.Form)] 
+10

私は 'filterContext.HttpContext.Request.Form'を使ってフォームコレクションにアクセスする代わりに、それを渡すことができると思います。 –

+0

HeavyWaveに感謝します。この場合、ActionExecutingContextとActionExecutedContextの使用に違いはありますか? ありがとう – zanona

+0

ActionExecutedContextは、コントローラのアクションメソッドの後に実行されるOnActionExecutedメソッドで使用されています。そのため、ActionExecutedContextでは、実行結果の一部にアクセスできます。 IntelliSenseでそれを試してみてください。 –

5

で 感謝を理解しやすいです願っています。

public override void OnActionExecuting(ActionExecutingContext context) 

コンテキストオブジェクトから、投稿データにアクセスします。

+0

ActionExecutingContext.RequestContext.HttpContext.Request.Formをチェックすると、そこでポスト値を取得できるはずです。 –

1

私はこの問題をASP.NET MVCのカスタムバインダーで解決します。

あなたの行動には次のような署名があるとします。

public ActionResult MyAction(MyParameter param) 
{ 
    if(param.isValid) 
    return View("valid"); 
    else 
    return View("invalid"); 
} 

MYPARAMクラス:

public class MyParameter 
    { 
     public string UserName{get;set;} 
     public string Password {get;set;} 

     public bool isValid 
     { 
     //check if password and username is valid. 
     } 

} 

アン、カスタムバインダー

public class CustomBinder:IModelBinder 
{ 
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
     { 
      var p = new MyParam(); 
      // extract necessary data from the bindingcontext like 
      p.UserName = bindingContext.ValueProvider["username"] != null 
         ? bindingContext.ValueProvider["username"].AttemptedValue 
         : ""; 
      //initialize other attributes. 
     } 
} 
+0

これは簡単な作業のための設計オーバーです。 @HeavyWaveは優れた単純なソリューションを提供しました。 – reflog

+0

Tss ...私は単純にそれを行うための他の方法を知らなかった:)。 –

3

この場合、ActionFilterAttributeを使用することをお勧めします。あなたがしたいことは、確かにAuthorize属性と同じではありません。

Authorize属性はコントローラ/アクションに共通ロジックを挿入するだけです。次のとおりです。

ユーザーがログインしていない場合は、ログインページにリダイレクトします。それ以外の場合は、アクションを実行します。

お客様のClientLoginアクションは、現時点では何をすべきかを実行します。
ロジックをActionFilterAttributeに渡すことは悪い設計です。

+0

あなたは正しいですが、1つのアクションでのみ使用する必要のあるものを属性に変換することはお勧めできません。承認は、アクションがユーザーに許可を必要とし、ロジックを含んでいないことを示します。 –

+0

はい、私はあなたが指摘していることを理解しています、実際には問題は、私はアプリケーションの上でクライアントによって実行されるいくつかの異なるアクションがあるだろう、これはクライアントにログインする必要がありますログインページ。 私はそれがはるかに簡単で美しいと思っていた(私は今ASP.NETについて始めているので、何か間違ったことについて申し訳ありません)、各メソッドの先頭に[ValidateAsClient] 。しかし、私はこれが正しいと確信していません、あなたの入力のおかげで – zanona

+0

まあ、それはあなたのやり方をするために何かを壊すことはありません。 :)そのように属性を使用するだけでは完全に自然ではありません。それで全部です。 –