ASP.NET MVC筛选器之特殊筛选器IOverrideFilter
来源:互联网 发布:oracle数据库搜索引擎 编辑:程序博客网 时间:2024/06/05 17:45
这个筛选器的特殊之处在于他控制的是筛选器,既不是控制Controller,也不是Action,更不是全局或者权限之类的。
IOverrideFilter 有5个继承的封闭类
分别为:OverrideActionFiltersAttribute,OverrideAuthenticationAttribute,OverrideAuthorizationAttribute,OverrideExceptionFiltersAttribute,OverrideResultFiltersAttribute他们都是继承自 Attribute, IOverrideFilter。
惊奇的发现,这些密封类既不能作为特性放在Controller和Action上,也不能作为全局筛选器添加到GlobalFilter。
经过研究发现,假如把OverrideActionFiltersAttribute作为特性放到Action 上面
比如: [OverrideActionFilters] public ActionResult Index() { return View(); }
这样写,丝毫不起作用,且在获取ActionAttribute的时候,直接被过滤掉了。究起原因,Get Action Attribute 的时候,他会判断是否当前Action的特性是否继承自FilterAttribute,很明显OverrideActionFiltersAttribute等五个密封类只是继承自 Attribute, IOverrideFilter。直接被过滤掉了,无论你把这个特性添加到Controller或者Action上,丝毫不起作用。
那么放在全局GlobalFilter上呢?
比如这样写: public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); OverrideActionFiltersAttribute OE = new OverrideActionFiltersAttribute(); filters.Add(OE); } }
这样写,程序运行直接报错。错误是 throw new InvalidOperationException(Properties.MvcResources.GlobalFilterCollection_UnsupportedFilterInstance);
这是什么错误?
研究发现,在GlobalFilters.Add 方法的时候,他会调用 ValidateFilterInstance(filter);
private static void ValidateFilterInstance(object instance) { if (instance != null && !(instance is IActionFilter || instance is IAuthorizationFilter || instance is IExceptionFilter || instance is IResultFilter)) { throw new InvalidOperationException(Properties.MvcResources.GlobalFilterCollection_UnsupportedFilterInstance); } }
OE是传递到ValidateFilterInstance的 Instance参数,首先会判断OE是否等于NULL,然后OE必须是IActionFilter,AuthorizationFilter,IExceptionFilter,IResultFilter这四个筛选器其中之一,很明显上面说了OverrideActionFiltersAttribute等五大密封类并没有实现这些筛选器,他只是继承了 Attribute, IOverrideFilter。
那么问题很明显了,程序直接跳到 throw new InvalidOperationException 报错了。
既然全局GlobalFilter 和特性并不能让IOverrideFilter起作用,那么筛选器提供组件有三个,还有一个是ControllerInstanceFilterProvider可不可以呢?
public class ControllerInstanceFilterProvider : IFilterProvider { public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { if (controllerContext.Controller != null) { // Use FilterScope.First and Order of Int32.MinValue to ensure controller instance methods always run first yield return new Filter(controllerContext.Controller, FilterScope.First, Int32.MinValue); } } }
很可惜啊,这个所谓ControllerInstanceFilterProvider并没有提供添加筛选器组件的接口或者类。
那么IOverrideFilter该怎么实现呢?
上面用OverrideActionFiltersAttribute做了两个例子,一个是全局,一个是特性,都不行,都会出现问题,解决第一个问题,可以让实现的 IOverrideFilter继承自FilterAttribute接口。
public abstract class OverrideAttribute:FilterAttribute,IOverrideFilter { public Type FiltersToOverride { get { return typeof(IActionFilter); } } } public class Over : OverrideAttribute { }
首先写一个类OverrideAttribute,让他继承自FilterAttribute,IOverrideFilter,继承自FilterAttribute是为了解决上面出现的第一个问题,继承自IOverrideFilter是我们要实现的筛选器控制筛选器。
然后在Index Action上面应用拥有IOverrideFilter特性的Over
[Over]
public ActionResult Index()
{
return View();
}
这样,在Index 前面的所有筛选器,比如Controller的筛选器,Global的筛选器,全部无效。
定义两个Action筛选器
public abstract class FilterBaseAttribute:FilterAttribute,IActionFilter { public void OnActionExecuted(ActionExecutedContext filterContext) { } public void OnActionExecuting(ActionExecutingContext filterContext) { } } public class FooAttribute : FilterBaseAttribute { } public class BarAttribute : FilterBaseAttribute { }
在Index Action上面同时应用Action和OverrideFilter筛选器,在Controller上应用一个Action筛选器
[Foo] public class HomeController : Controller { [Over] [Bar] [OverrideActionFilters] public ActionResult Index() { return View(); } }
执行之后,你会发现,在Controller上面的Foo并没有被执行,而是被Over特性给过滤掉了,而Index Action上的Bar特性则被执行了。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
第二个问题怎么解决呢?
可以让 OverriderFilter筛选器同时继承自 IActionFilter和FilterAttribute以及他自身IOverrideFilter ,继承Action是为了执行目的,继承FilterAttribute是为了在全局添加的时候避开异常,达到Action递归链。继承自身是为了控制其它筛选器。
先就这么多吧,过几天再写解决方法。
- ASP.NET MVC筛选器之特殊筛选器IOverrideFilter
- ASP.NET MVC 中的动态操作筛选器
- 深入探讨ASP.NET MVC的筛选器
- 深入探讨ASP.NET MVC的筛选器
- ASP.NET 2.0移动开发之定义设备筛选器
- MVC中的筛选器
- 我要学ASP.NET MVC 3.0(十一): MVC 3.0 使用筛选器
- Asp.net MVC3教程(11) MVC 3.0 使用筛选器
- MVC 3.0 使用筛选器
- MVC 3.0 使用筛选器
- 筛选器
- 我要学ASP.NET MVC 3.0(十七): MVC 3.0 实例之表格中数据的筛选
- MVC四大筛选器—ActionFilter&ResultedFilter
- c# .net mvc webapi Filters 筛选器中获取 请求参数和响应内容
- DirectShow筛选器和筛选器图形
- 我要学ASP.NET MVC 3.0(十八): MVC 3.0 实例系列之表格中合并排序、分页和筛选
- Asp.Net MVC5代码的筛选器(ActionFilter)执行递归链表分析
- 排序、 筛选和分页与 ASP.NET MVC 应用程序中的实体框架
- 【BZOJ1003】物流运输(ZJOI2006)-DP+最短路
- Eigen
- golang生成ssh 密钥方法
- softmax 反向传播
- 读书笔记之初见JVM内存区域
- ASP.NET MVC筛选器之特殊筛选器IOverrideFilter
- 【LeetCode】268. Missing Number
- Ubuntu16.04下同时安装CUDA8.0和CUDA7.0
- 杭电ACM OJ 1025 Constructing Roads In JGShining's Kingdom 最长上升子序列 O(nlogn)算法详解+回溯暴力解决+动态规划dp优雅解决
- centos7 k8s v1.8.4 所有节点运行环境一键准备脚本
- 11.25's
- Quartz 学习总结
- 项目中常用的css样式总结
- Keil4安装和破解过程