2009-10-21 87 views
5

其實我有一個應用程序使用WebService來檢索某些客戶端信息。 所以我驗證我的ActionResult內的登錄信息,如:ASP.NET MVC - ActionFilterAttribute驗證POST數據

[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用戶名和密碼

但我的信息返回boolean值的方法改變了我的想法,我想在該方法的開頭使用那個很好的ActionFilterAttributes,所以如果Client.validate()返回true,就和[Authorize]一樣,但是使用我自定義的webservice,所以我會有類似的東西:

[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,password = postingPassword)]以及如何使函數ValidateAsClient正常工作?

我希望這是很容易理解提前

回答

7

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

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

} 

的那麼定製綁定像這樣的東西可能是:

[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'訪問表單集合,而不是傳遞它。 – 2009-10-21 15:54:13

+0

感謝那個HeavyWave非常好,另一個問題:在這種情況下使用ActionExecutingContext和ActionExecutedContext是否有區別? 謝謝 – zanona 2009-10-21 16:00:08

+0

ActionExecutedContext應該用在OnActionExecuted方法中,該方法在控制器的操作方法之後執行。所以在ActionExecutedContext中你可以訪問一些執行的結果。只需使用IntelliSense進行遊戲即可。 – 2009-10-21 16:12:22

5

應覆蓋以下方法 感謝。

public override void OnActionExecuting(ActionExecutingContext context) 

並從上下文對象訪問您的發佈數據。

+0

檢查ActionExecutingContext.RequestContext.HttpContext.Request.Form,你應該能夠在那裏獲取帖子值。 – 2009-10-21 15:25:18

1

我會用ASP.NET MVC中的一個自定義綁定來解決這個問題。

假設您的操作將具有以下簽名。

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

MyParam類:

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 2010-07-18 16:54:24

+0

Tss ...我簡單的不知道其他方式來做到這一點:)。 – 2010-07-20 11:04:27

3

我認爲在這種情況下使用ActionFilterAttribute不是一個好主意。而你想要做的絕對不是Authorize屬性所做的。

Authorize屬性只是將一個公共邏輯注入控制器/操作。它是:

重定向到登錄頁面,如果用戶沒有登錄。否則讓這個動作被執行。

您的ClientLogin行動只是做它現在應該做的。
將這個邏輯運用到ActionFilterAttribute將是一個糟糕的設計。

+0

你說得對,把一個只能被一個Action使用的東西變成一個屬性並不是一個好主意。授權表示該操作要求用戶被授權,它不包含任何邏輯。 – 2009-10-21 15:26:30

+0

是的,我明白你的意思,實際上問題是我會在客戶端應用程序中執行幾個不同的操作,這將要求客戶端登錄,否則會將他重定向到登錄頁面。 所以我認爲它可以更容易和美觀(因爲我是一個ASP.NET開始,所以對任何錯誤應用抱歉)把一個[ValidateAsClient]放在每個方法的開始。但我不確定這是否正確,謝謝您的輸入 – zanona 2009-10-21 15:46:54

+0

好吧,它不會破壞任何事情,以您的方式。 :)這樣使用屬性並不是完全自然的。就這樣。 – 2009-10-21 15:59:51