我正在实现一个继承自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()
{
}
}
答案 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用户),则会调用两个控制器的唯一实例,因此一个实例不知道另一个实例已经运行了过滤器。