2009-10-21 3 views
5

실제로 일부 클라이언트 정보를 검색하는 데 WebService를 사용하는 응용 프로그램이 있습니다. 그래서 내가 좋아하는 내 ActionResult 내부의 로그인 정보를 검증 하였다POST 데이터를 확인하는 ASP.NET MVC - 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()가 [Authorize]와 똑같지 만 내 사용자 지정 웹 서비스를 반환하면 렌더링됩니다. 다음과 같이 입력하십시오 :

[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

아마 이런 식으로 뭔가

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

나는 그것을 넘겨주는 대신에'filterContext.HttpContext.Request.Form'을 사용하여 폼 콜렉션에 접근 할 수 있다고 생각합니다. –

+0

그 HeavyWave 주셔서 감사합니다. 또 다른 질문 :이 경우에는 ActionExecutingContext와 ActionExecutedContext를 사용하는 것에 차이가 있습니까? 감사합니다. – zanona

+0

ActionExecutedContext는 컨트롤러의 조치 메소드 다음에 실행되는 OnActionExecuted 메소드에서 사용되어야합니다. 따라서 ActionExecutedContext에서 실행 결과의 일부에 액세스 할 수 있습니다. IntelliSense를 가지고 놀아보십시오. –

5

다음과 같은 메소드를 오버라이드 (override)에 감사를 쉽게 이해할 수 있기를 바랍니다.

public override void OnActionExecuting(ActionExecutingContext context) 

그리고 컨텍스트 개체에서 게시물 데이터에 액세스하십시오.

+0

ActionExecutingContext.RequestContext.HttpContext.Request.Form을 확인하면 거기에서 게시물 값을 가져올 수 있어야합니다. –

1

ASP.NET MVC에서 사용자 지정 바인더로이 문제를 해결할 수 있습니다.

동작에 다음과 같은 서명이 있다고 가정합니다. 이 같은

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

그리고 그것을 사용 :

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

맞습니다. 하나의 액션에서만 사용해야하는 것을 속성으로 바꾸는 것은 좋지 않습니다. 권한 부여는 조치에 사용자의 승인이 필요하다는 것을 나타내며 논리를 포함하지 않습니다. –

+0

네, 이해합니다. 사실, 문제는 앱 전체에서 클라이언트가 수행해야 할 몇 가지 다른 작업을 수행해야한다는 것입니다. 그러면 클라이언트에 로그인해야합니다. 그렇지 않으면 클라이언트가 리디렉션 될 것입니다. 로그인 페이지. 그래서 제가 생각하기에 훨씬 쉽고 아름답습니다 (ASP.NET에서 시작한 이후로 말할 수 있듯이 잘못 적용된 것에 대해 유감스럽게 생각합니다). 각 메소드의 시작 부분에 [ValidateAsClient]를 넣어야합니다. . 하지만 이것이 정확한지 확신 할 수 없습니다. 귀하의 의견에 감사드립니다. – zanona

+0

글쎄, 그것은 당신의 방식대로하는 것이 무엇이든 부러지지 않을 것입니다. :) 그런 식으로 속성을 사용하는 것은 전적으로 자연스럽지 않습니다. 그게 다야. –