2009-10-21 10 views
5

Aktualnie mam aplikację korzystającą z usługi WebService do pobierania informacji o niektórych klientach. Więc ja walidacji danych logowania w mojej ActionResult jak:ASP.NET MVC - ActionFilterAttribute do sprawdzania danych 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"); 
    } 
} 

Gdzie Client.Validate() to metoda, która zwraca wartość logiczną na podstawie informacji dostarczonych na nazwę użytkownika i hasło POST

Ale zmienił zdanie i chciałbym użyć tego ładnego ActionFilterAttributes na początku metody, więc będzie on renderowany tylko wtedy, gdy Client.validate() zwróci true, tak samo jak [Authorize], ale z moim niestandardowym webservice, więc chciałbym mieć coś takiego:

[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') 
} 

a następnie wewnątrz ValidateAsClient chciałbym mieć coś takiego:

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

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

Więc mój problem jest, nie wiem dokładnie, jak to działało, bo nie wiem jak przekazać dydaktyczna do [ValidateAsClient (username = postedUsername, password = postedPassword)] a także, w jaki sposób mogę sprawić, aby funkcja ValidateAsClient działała poprawnie?

Mam nadzieję, że to jest łatwe do zrozumienia góry dzięki

Odpowiedz

7

Coś w tym chyba:

[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 
    } 
} 

i używać go tak:

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

Myślę, że można uzyskać dostęp do kolekcji formularza z 'filterContext.HttpContext.Request.Form', zamiast przekazywania go. –

+0

dzięki za to HeavyWave bardzo dobre, kolejne pytanie: czy jest jakaś różnica między użyciem ActionExecutingContext i ActionExecutedContext w tym przypadku? Dzięki – zanona

+0

ActionExecutedContext ma być używany w metodzie OnActionExecuted, która jest wykonywana po metodzie akcji kontrolera. Tak więc w ActionExecutedContext masz dostęp do niektórych wyników wykonania. Po prostu baw się tym z IntelliSense. –

5

powinien zastąpić następującą metodę.

public override void OnActionExecuting(ActionExecutingContext context) 

I z obiektu kontekstu, uzyskaj dostęp do swoich danych pocztowych.

+0

Sprawdź ActionExecutingContext.RequestContext.HttpContext.Request.Form i powinieneś być w stanie pobrać tam wartość postu. –

1

Rozwiązałbym ten problem z niestandardowym segregatorem w ASP.NET MVC.

Załóżmy, że Twoje działanie będzie miało następujący podpis. Klasa

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. 
     } 

} 

wówczas zwyczaj spoiwo

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

To jest projekt na proste zadanie. @HeavyWave zapewnił doskonałe i proste rozwiązanie. – reflog

+0

Tss ... Zwykle nie znałem innych sposobów na zrobienie tego :). –

3

Nie wydaje mi się, że warto w tym przypadku użyć ActionFilterAttribute. A to, co chcesz zrobić, to zdecydowanie nie to samo, co atrybut Authorize.

Atrybut Authorize po prostu wprowadza wspólną logikę do kontrolera/akcji. Który jest:

Przekieruj do strony logowania, jeśli użytkownik nie jest zalogowany. Inaczej pozwól, aby akcja została wykonana.

Twoja akcja ClientLogin robi dokładnie to, co powinna teraz robić.
Byłoby źle zaprojektować, aby przenieść tę logikę na ActionFilterAttribute.

+0

Masz rację, nie jest dobrym pomysłem, aby włączyć coś, co powinno być używane tylko przez jedną Akcja do atrybutu. Autoryzacja wskazuje, że działanie wymaga autoryzacji użytkownika, nie zawiera żadnej logiki. –

+0

Tak, rozumiem, że chodzi o ciebie, tak naprawdę problem polegał na tym, że musiałbym wykonać kilka różnych czynności przez klienta w całej aplikacji, a to wymagałoby zalogowania się klienta, inaczej przekieruje go do Strona logowania. Więc myślałem, że to może być dużo łatwiejsze i piękne (jak mogę powiedzieć na razie odkąd jestem zapoczątkowany na ASP.NET, tak przepraszam za wszystko co się stało), aby umieścić [ValidateAsClient] na początku każdej metody . Ale nie jestem pewien, czy to jest poprawne, dzięki za twoje dane wejściowe – zanona

+0

Cóż, nie złamie to niczego, aby zrobić to po swojemu. :) Po prostu nie całkiem naturalne, aby użyć tego atrybutu w ten sposób. To wszystko. –

Powiązane problemy