Asp.net mvc ASP.NET MVC-用于验证POST数据的ActionFilterAttribute

Asp.net mvc ASP.NET MVC-用于验证POST数据的ActionFilterAttribute,asp.net-mvc,post,httprequest,actionfilterattribute,Asp.net Mvc,Post,Httprequest,Actionfilterattribute,实际上,我有一个应用程序正在使用Web服务检索一些客户机信息。 因此,我正在验证ActionResult中的登录信息,如: [AcceptVerbs(HttpVerbs.Post)] public ActionResult ClientLogin(FormCollection collection) { if(Client.validate(collection["username"], collection["password"])) { Session["us

实际上,我有一个应用程序正在使用Web服务检索一些客户机信息。 因此,我正在验证ActionResult中的登录信息,如:

[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')
}
public class ValidateAsClient : ActionFilterAttribute
{
    public string username { get; set; }
    public string password { get; set; }

    public Boolean ValidateAsClient()
    {
        return Client.validate(username,password);
    }
}
然后在ValidateAsClient中,我会有如下内容:

[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')
}
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=postedPassword)],还有,我如何让函数ValidateAsClient正常工作

我希望这很容易理解
提前感谢

您应该覆盖以下方法

public override void OnActionExecuting(ActionExecutingContext context)

然后从context对象访问您的帖子数据。

我将使用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.
        }
}

大概是这样的:

[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)]

我认为在这种情况下使用
ActionFilterAttribute
不是一个好主意。您想要做的事情肯定与
Authorize
属性不一样

Authorize
属性只是将公共逻辑注入控制器/操作中。即:

如果用户未登录,则重定向到登录页面。否则就让动作执行

您的
ClientLogin
操作正是它目前应该做的。

将该逻辑带到
ActionFilterAttribute

检查ActionExecutingContext.RequestContext.HttpContext.Request.Form是一个糟糕的设计,您应该能够在那里获取post值。您是对的,将只应由一个操作使用的内容转换为属性不是一个好主意。Authorize表示该操作需要用户被授权,它不包含任何逻辑。是的,我理解你的观点,实际上问题是我会让客户端在整个应用程序中执行几个不同的操作,这将要求客户端登录,否则会将其重定向到登录页面。所以我想在每个方法的开头加上一个[ValidateAsClient]可能会更简单、更漂亮(因为我现在是ASP.NET的初学者,所以很抱歉应用了任何错误)。但我不确定这是否正确,谢谢你的投入。按你的方式做不会破坏任何东西这样使用属性并不完全自然。仅此而已。我认为您可以使用
filterContext.HttpContext.Request.form
访问表单集合,而不是将其传递给其他人。感谢这一重量级内容非常好,还有一个问题:在这种情况下,使用ActionExecutingContext和ActionExecuteContext有什么区别吗?ThanksActionExecutedContext应该在OnActionExecuted方法中使用,该方法在控制器的action方法之后执行。所以在ActionExecutedContext中,您可以访问一些执行结果。只需使用IntelliSense就可以了。这是一个简单任务的过度设计@HeavyWave提供了一个优秀而简单的解决方案。Tss。。。我不知道其他的方法:)。