ASP.NET MVC - ActionFilterAttribute 用于验证 POST 数据

发布于 2024-08-08 09:25:05 字数 1515 浏览 6 评论 0原文

实际上,我有一个使用 WebService 来检索一些客户端信息的应用程序。 因此,我正在验证 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')
}

然后在 ValidateAsClient 中我会比如:

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

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

所以我的问题是,我不知道如何让它工作,因为我不知道如何将 POSTED 信息传递给 [ValidateAsClient(username=postedUsername,password=postedPassword)]< /b> 另外,如何使 ValidateAsClient 函数正常工作?

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

Actually I have an application that is using a WebService to retrieve some clients information.
So I was validating the login information inside my ActionResult like:

[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");
    }
}

Where Client.Validate() is a method that returns a boolean based on the information provided on the POST username and password

But I changed my mind and I would like to use that nice ActionFilterAttributes at the beginning of the method so it will just be rendered if the Client.validate() return true, just the same as [Authorize] but with my custom webservice, so I would have something like:

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

and then inside the ValidateAsClient I would have something like:

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

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

So my problem is, I don't know exactly how to make it work, because I don't know how to pass the POSTED information to the [ValidateAsClient(username=postedUsername,password=postedPassword)] and also, how could I make the function ValidateAsClient work properly?

I hope this is easy to understand
Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

薯片软お妹 2024-08-15 09:25:05

可能是这样的:

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

Something like this probably:

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

And use it like this:

[ValidateAsClient(HttpContext.Request.Form)]
时光是把杀猪刀 2024-08-15 09:25:05

您应该重写以下方法。

public override void OnActionExecuting(ActionExecutingContext context)

并从上下文对象中访问您的帖子数据。

You should override the following method.

public override void OnActionExecuting(ActionExecutingContext context)

And from the context object, access your post data.

憧憬巴黎街头的黎明 2024-08-15 09:25:05

我认为在这种情况下使用 ActionFilterAttribute 不是一个好主意。而你想要做的事情绝对与 Authorize 属性所做的不一样。

Authorize 属性只是将通用逻辑注入控制器/操作中。这是:

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

您的 ClientLogin 操作恰好执行了当前应该执行的操作。
将该逻辑转移到 ActionFilterAttribute 是一个糟糕的设计。

I don't think it's a good idea to use an ActionFilterAttribute in this case. And what you want to do is definitely not the same as Authorize attribute does.

The Authorize attribute just injects a common logic into a controller/action. Which is :

Redirect to login page, if the user is not logged in. Else let the action be executed.

Your ClientLogin action does just what it's supposed to do at the moment.
It would be a bad design to carry that logic over to an ActionFilterAttribute.

失退 2024-08-15 09:25:05

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

I would solve this problem with a custom binder in ASP.NET MVC.

Suppose your action will have the following signature.

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

MyParam class:

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

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

}

An then the custom binder

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.
        }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文