MVC 中的操作过滤器和授权属性导致对象引用错误
本文关键字:属性 对象引用 错误 授权 操作 过滤器 MVC | 更新日期: 2023-09-27 18:34:54
我正在使用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
}
如果我们看一下代码,我首先使用了继承ActionFilterAttribute
类SessionExpire
属性,它检查session
是否对当前请求有效并在那里执行一些重定向。接下来,我正在检查继承AuthorizeAttribute
类AuthorizeSubscription
属性。它还根据那里编写的逻辑执行一些重定向。
在EditProduct
行动中,我使用了另一个AuthorizeAttribute
。
如果我点击 url 进行StoreDetail
操作而不进行任何session
,它会将我重定向到所需的页面。
但是如果我点击 url 进行EditProduct
操作,它会让我Object Reference error
.在调试期间,它首先进入AuthorizeProdcutEdit
的代码,并且找不到Session
Null。
为什么它不先执行SessionExpire
代码,如果发现 Null Session
则从那里退出?
Per MSDN:
筛选器按以下顺序运行:
- 授权筛选器
- 操作筛选器
- 响应筛选器
- 异常筛选器
SessionExpire
属性在AuthorizeSubscription
属性之后触发的原因是 MVC 始终首先触发授权筛选器。
因此,要解决此问题,您需要SessionExpire
来实现IAuthorizationFilter
(并且可能继承Attribute
(。
此外,还需要设置属性的顺序,因为 .NET 框架不保证处理属性的顺序。
[SessionExpire(Order=1)]
[AuthorizeSubscription(Order=2)]
public class StoreController : Controller
{
// Remaining implementation...
请注意,最好的方法是将筛选器与属性分开,这样既允许它们对 DI 友好,又允许您通过按特定顺序全局注册筛选器来显式设置顺序。
根据 MSDN,筛选属性的顺序首先由其类型(例如授权筛选器、操作筛选器等(确定,然后由其作用域(例如控制器作用域、操作作用域(确定。
SessionExpire
属性的类型为"操作"、"作用域控制器"。AuthorizeProductEdit
属性的类型为"授权"、"范围操作"。
这就是您的AuthorizeProductEdit
属性首先出现的原因。
来自文档(我的强调(
ASP.NET MVC 框架支持四种不同类型的筛选器:
授权筛选器 – 实现 IAuthorizationFilter 属性。
操作筛选器 – 实现 IActionFilter 属性。
结果筛选器 – 实现 IResultFilter 属性。
异常筛选器 – 实现 IExceptionFilter 属性。
筛选器按上面列出的顺序执行。例如,授权筛选器始终在操作筛选器之前执行,异常筛选器始终在每种其他类型的筛选器之后执行。