MVC中的ActionFilter和Authorize Attribute导致对象引用错误

时间:2016-02-17 10:04:13

标签: c# asp.net-mvc controller action-filter authorize-attribute

我正在使用MVC4来构建ASP.NET应用程序。我在我的业务逻辑中使用ActionFilterAttributeAuthorizeAttribute。以下是示例代码

控制器类

[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则从那里退出?

3 个答案:

答案 0 :(得分:4)

MSDN

  

过滤器按以下顺序运行:

     
      
  1. 授权过滤器
  2.   
  3. 操作过滤器
  4.   
  5. 响应过滤器
  6.   
  7. 例外过滤器
  8.   

您的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属性。

     

过滤器按上面列出的顺序执行。例如,授权过滤器始终在操作过滤器之前执行,并且异常过滤器始终在每种其他类型的过滤器之后执行。