我正在使用MVC4
来构建ASP.NET
应用程序。我在我的业务逻辑中使用ActionFilterAttribute
和AuthorizeAttribute
。以下是示例代码
控制器类
[SessionExpire]
[AuthorizeSubscription]
public class StoreController : Controller
{
public ActionResult StoreDetail()
{
// My logic goes here
}
[AuthorizeProductEdit]
[HttpGet]
public ActionResult EditProduct()
{
// My logic goes here
}
如果我们查看代码,我首先使用继承SessionExpire
类的ActionFilterAttribute
属性,检查session
是否对当前请求有效并在那里进行重定向。接下来,我正在检查继承AuthorizeSubscription
类的AuthorizeAttribute
属性。它还根据写在那里的逻辑进行一些重定向。
在EditProduct
行动中,我使用了另一个AuthorizeAttribute
。
如果我在没有StoreDetail
的情况下点击session
操作的网址,则会将我重定向到所需的网页。
但是,如果我点击了EditProduct
动作的网址,它会抛出Object Reference error
。在调试期间它首先进入AuthorizeProdcutEdit
的代码,但找不到Session
Null失败。
为什么它没有先执行SessionExpire
代码,如果找到Session
Null则从那里退出?
答案 0 :(得分:4)
每MSDN:
过滤器按以下顺序运行:
- 授权过滤器
- 操作过滤器
- 响应过滤器
- 例外过滤器
醇>
您的SessionExpire
属性在AuthorizeSubscription
属性之后触发的原因是因为MVC始终首先触发授权过滤器。
因此,要解决该问题,您需要SessionExpire
来实施IAuthorizationFilter
(并且可能会继承Attribute
)。
此外,您需要set the order of your attributes,因为.NET框架不保证将处理它们的顺序。
[SessionExpire(Order=1)]
[AuthorizeSubscription(Order=2)]
public class StoreController : Controller
{
// Remaining implementation...
请注意,最好的方法是separate your filters from your attributes,它们都允许它们对DI友好,并且还允许您通过按特定顺序全局注册过滤器来明确设置顺序。
答案 1 :(得分:1)
根据MSDN,过滤属性的顺序首先由其类型(例如授权过滤器,动作过滤器等)确定,然后由其范围(例如控制器范围,操作范围)确定。
您的SessionExpire
属性的类型为Action,范围为Controller。
您的AuthorizeProductEdit
属性的类型为Authorization,范围为Action。
这就是您的AuthorizeProductEdit
属性首先出现的原因。
答案 2 :(得分:1)
来自documentation(我的重点)
ASP.NET MVC框架支持四种不同类型的过滤器:
授权过滤器 - 实现IAuthorizationFilter属性。
动作过滤器 - 实现IActionFilter属性。
结果过滤器 - 实现IResultFilter属性。
异常过滤器 - 实现IExceptionFilter属性。
过滤器按上面列出的顺序执行。例如,授权过滤器始终在操作过滤器之前执行,并且异常过滤器始终在每种其他类型的过滤器之后执行。