相同的动作过滤不同的动作

时间:2014-01-09 01:41:08

标签: asp.net-mvc lifecycle actionfilterattribute custom-action-filter

我正在实现一个继承自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()
  {
  }
}

2 个答案:

答案 0 :(得分:3)

不要这样做。

根据我自己的经验,在Action上使用私有变量是不可靠的,即使它有时似乎有效,你也可能最终得到一些非决定性的东西。

请参阅,您的代码可能在1个请求中正常工作,但在同时处理多个请求时根本无法正常工作。

此用户的问题是声称与您完全相反的体验:How to use ActionFilterAttribute to log running times?

我唯一的解释是,如果Action Invoker实例化动作过滤器,那么:它不会使它保持很长时间,或者它会创建一个实例池(或两者)。

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

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

我建议将其操作集中在使用过滤器上下文。过滤器上下文包含此请求正在进行的所有操作。在MVC中,您可以使用 filterContext.HttpContext.Items 来存储正在用于此特定请求的项目。 (见Accessing Action Filter's data in Controller Action

最后,还可能会发现不同版本的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

答案 1 :(得分:0)

该网站非常了解MVC中的页面生命周期

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

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