常用过滤器
1.授权过滤器
- 说明:它是过滤器管道中第一个过滤器,控制对方法的访问,仅有在它之前执行的方法,没有之后;在授权过滤器中不会处理异常, 异常过滤器也捕获到其中产生的异常,因此要小心应对。
- 实现:继承Attribute类,实现IAuthorizationFilter接口,重写OnAuthorization方法。
注:继承Attribute类的目的是可以该过滤器以特性的形式作用于Controller或Action,下面过滤器都类似,不再说明。 - 用途:通常用来做权限校验
2. 资源过滤器
- 说明:只有授权过滤器在资源过滤器之前运行,里面的OnResourceExecuting重写是在创建控制器调用的。
- 实现:继承Attribute类,实现IResourceFilter接口,重写OnResourceExecuting 和 OnResourceExecuted方法。
(异步的话实现IAsyncResourceFilter接口,重写OnResourceExecutionAsync方法) - 用途:做一些对变化要求不高的页面进行资源缓存 、防盗链等操作
3. 操作过滤器(行为过滤器)
- 说明:分别在操作方法之前和之后执行
- 实现:继承Attribute类,实现IActionFilter接口,重写OnActionExecuting 和 OnActionExecuted方法。 或者直接继承ActionFilterAttribute类,观察源码可知,该类继承了Attribute类,而且还实现IActionFilter,IResultFilter接口。(异步的话实现IAsyncActionFilter接口,重写OnActionExecutionAsync方法)
4. 结果过滤器
- 说明:在方法执行前后,且操作过滤器之后;结果(如:页面渲染)的前后运行。
- 实现:继承Attribute类,实现IResultFilter接口,重写OnResultExecuting 和 OnResultExecuted方法。 或者直接继承ResultFilterAttribute类,(或ActionFilterAttribute类), 观察源码可知,该类继承了Attribute类,而且还实现IResultFilter接口。(异步的话实现IAsyncActionFilter接口, 重写OnActionExecutionAsync方法) 还可以实现:IAlwaysRunResultFilter 或 IAsyncAlwaysRunResultFilter 接口。
- 用途:可以获取action的返回结果,进行一些处理,比如:可以对结果进行格式化、大小写转换等。
5. 异常过滤器
- 说明:用于实现常见的错误处理策略,没有之前和之后事件,处理 Razor 页面或控制器创建、模型绑定、操作过滤器或操作方法中发生的未经处理的异常。 但无法捕获资源过滤器、结果过滤器或 MVC 结果执行中发生的异常 。
- 实现:继承Attribute类,实现IExceptionFilter接口,重写OnException方法。 或者直接继承ExceptionFilterAttribute类,观察源码可知,该类继承了Attribute类,而且还实现IExceptionFilter接口。(异步的话实现 IAsyncExceptionFilter接口,重写OnExceptionAsync方法)
- 用途:全局捕获异常,进行相关处理。
执行顺序
异常过滤器不参与测试,测试剩余四个过滤器的执行顺序,将四个过滤器在下面Index方法上,经断点测试执行顺序如下:
-
[KuResultFilter]//结果过滤器 -- 生成前后扩展 [KuResourceFilter]//资源过滤器--缓存 [KuActionFilter]//操作过滤器(行为过滤器)---执行方法前后的记录 [KuAuthFilter]//授权过滤器-权限验证 public IActionResult Index() { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--执行[Index]方法:" + this.GetType().Name + "---" + DateTime.Now); return View(); }
- 授权过滤器(OnAuthorization)→资源过滤器(OnResourceExecuting)→创建控制器(HomeController---构造函数) →操作过滤器(OnActionExecuting)→执行action业务(HomeController----执行[Index]方法:) →操作过滤器(OnActionExecuted)→结果过滤器(OnResultExecuting)→页面渲染加载( Index.cshtml)→结果过滤器(OnResultExecuted)→资源过滤器(OnResourceExecuted)
测试顺序代码
- [KuAuthFilter]//授权过滤器-权限验证
public class KuAuthFilterAttribute : Attribute, IAuthorizationFilter { public KuAuthFilterAttribute() { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--KuAuth--构造函数---" + DateTime.Now); } public void OnAuthorization(AuthorizationFilterContext context) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--OnAuthorization---" + DateTime.Now); } }
- [KuResourceFilter]//资源过滤器--缓存
public class KuResourceFilterAttribute : Attribute, IResourceFilter { public KuResourceFilterAttribute() { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--Resource--构造函数---" + DateTime.Now); } /// <summary> /// 在xx资源之前 /// 执行资源筛选器。 在执行管道的其余部分之前调用。 /// </summary> /// <param name="context"></param> /// <exception cref="NotImplementedException"></exception> public void OnResourceExecuting(ResourceExecutingContext context) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--Resource--之前(OnResourceExecuting)---" + DateTime.Now); } /// <summary> /// 在xx资源后 /// 执行资源筛选器。 在执行管道的其余部分后调用。 /// </summary> /// <param name="context"></param> /// <exception cref="NotImplementedException"></exception> public void OnResourceExecuted(ResourceExecutedContext context) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--Resource--之后(OnResourceExecuted)---" + DateTime.Now); Console.WriteLine("------------------------------------" + DateTime.Now); } }
- [KuActionFilter]//操作过滤器(行为过滤器)---执行方法前后的记录
public class KuActionFilterAttribute : Attribute, IActionFilter { public KuActionFilterAttribute() { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--Action--构造函数---" + DateTime.Now); } /// <summary> /// 在XXAction执行之前 /// </summary> /// <param name="context"></param> public void OnActionExecuting(ActionExecutingContext context) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--Action--之前(OnActionExecuting)---" + DateTime.Now); } /// <summary> /// 在XXAction执行之后 /// </summary> /// <param name="context"></param> public void OnActionExecuted(ActionExecutedContext context) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--Action--之后(OnActionExecuted)---" + DateTime.Now); } }
- [KuResultFilter]//结果过滤器 -- 生成前后扩展
public class KuResultFilterAttribute : Attribute, IResultFilter { public KuResultFilterAttribute() { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}---Result--构造函数---" + DateTime.Now); } /// <summary> /// 在xx结果之前 /// </summary> /// <param name="context"></param> /// <exception cref="NotImplementedException"></exception> public void OnResultExecuting(ResultExecutingContext context) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--Result---之前(OnResultExecuting)---" + DateTime.Now); } /// <summary> /// 在xx结果之后 /// </summary> /// <param name="context"></param> /// <exception cref="NotImplementedException"></exception> public void OnResultExecuted(ResultExecutedContext context) { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--Result---之后(OnResultExecuted)---" + DateTime.Now); } }
- 控制器
public class HomeController : Controller { public HomeController() { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}---{this.GetType().Name}--构造函数---" + DateTime.Now); } [KuResultFilter]//结果过滤器 -- 生成前后扩展 [KuResourceFilter]//资源过滤器--缓存 [KuActionFilter]//操作过滤器(行为过滤器)---执行方法前后的记录 [KuAuthFilter]//授权过滤器-权限验证 public IActionResult Index() { Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}--执行[Index]方法:" + this.GetType().Name + "---" + DateTime.Now); return View(); } }
- Index.cshtml
@{ ViewData["Title"] = "Home Page"; Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}---{this.GetType().Name}--Index.cshtml---" + DateTime.Now); } <div class="text-center"> <h1 >.net</h1> </div>
- 执行效果