4

我正在实现一个从 AuthorizeAttribute 继承的自定义授权过滤器。经过我的研究,我发现动作过滤器被缓存了,所以它们只被实例化一次。

这是我的问题。如果我实现并使用如下所示的自定义操作过滤器,它应该无法正常工作,因为它会被实例化一次并且永远不会再次调用构造函数。但是当我测试时,它运行良好,所以我想有一些我不知道的东西。

谁能清楚地解释这个(动作过滤器生命周期?)?

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
  private readonly string value = string.Empty;

  public CustomAuthorizeAttribute(string value)
  {
     this.value = value;
  }

  protected override bool AuthorizeCore(HttpContextBase httpContext)
  {
     // Do something with this.value
  }
}

public class HomeController : Controller
{
  [CustomAuthorize("ACCESS_INDEX")]
  public ActionResult Index()
  {
  }

  [CustomAuthorize("ACCESS_LOGIN")]
  public ActionResult Login()
  {
  }
}
4

2 回答 2

4

不要这样做。

以我自己的经验,在 Action 上使用私有变量是不可靠的,即使它有时看起来有效,你最终可能会得到一些非决定性的东西。

看,您的代码可能适用于 1 个请求,但在同时处理多个请求时根本不起作用。

该用户的问题是声称与您完全相反的体验:如何使用 ActionFilterAttribute 记录运行时间?

我唯一的解释是,如果 Action Invoker 实例化了动作过滤器,并且要么:它不会将其保留很长时间,要么它会创建一个实例池(或两者兼而有之)。

我有一个原型,它将上下文作为私有操作属性,它偶尔会(不是每次)抛出与并发使用相关的 EF 错误(这对 EF 来说是一个问题。)

这告诉我,我的动作被不止一次地同时使用。

我建议将他们的操作集中在使用过滤器上下文。过滤器上下文包含此请求当前正在发生的所有事情。在 MVC 中,您可以利用filterContext.HttpContext.Items来存储用于此特定请求的项目。(请参阅在控制器操作中访问操作过滤器的数据

最后,还可以证明不同版本的 MVC 框架对动作过滤器的生命周期进行了不同的优化。

关于该主题的几个有用的链接:

关于一般 MVC 生命周期的一些细节 http://blog.christopheargento.net/2012/06/11/detailed-life-cycle-of-an-asp-net-mvc-request/

在谈论如何创建动态操作过滤器(以编程方式插入和动态更改)时,Dino Esposito 研究了一些正在发生的事情 https://msdn.microsoft.com/en-us/magazine/gg309182.aspx

自定义操作过滤器和多个存在时的过滤器顺序 http://www.asp.net/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-custom-action-filters

于 2015-03-05T18:28:12.713 回答
0

这个站点对 MVC 中的页面生命周期有一个非常好的概述

http://blogs.msdn.com/b/varunm/archive/2013/10/03/understanding-of-mvc-page-life-cycle.aspx

您的测试显示过滤器一直在运行的原因是,当从 URL MVC 调用路由时,会将其与控制器匹配,然后在该控制器中执行操作。找到一个动作 MVC 看到上面有一个动作过滤器,并将首先执行动作过滤器。如果在同一控制器中同时调用两个动作(来自两个不同的 Web 用户),则会调用控制器的两个唯一实例,因此一个实例不知道另一个实例已运行过滤器。

于 2014-01-09T02:07:25.680 回答