前言
上两篇文章分享了过滤器实现JWT进行鉴权,分别是通过授权过滤器和操作过滤器实现,这两个过滤器也是最常用的。文章链接:授权过滤器—MVC中使用授权过滤器实现JWT权限认证,操作过滤器—MVC中使用操作过滤器实现JWT权限认证,接下来将简单的谈谈资源过滤器在MVC中如何使用,一般项目中这个过滤器很少用到。
一、什么是资源过滤器?
过滤器(Filter)是 AOP(面向切面编程) 思想的一种实现,供我们在执行管道的特定阶段执行代码,通过使用过滤器可以实现短路请求、缓存请求结果、日志统一记录、参数合法性验证、异常统一处理、返回值格式化 等等,同时使业务代码更加简洁单纯,避免很多重复代码。所以在我们的过滤器中,大部分过滤器有开始执行action,即ing 状态的方法,也有action业务代码执行完后触发的ed状态的方法。.
资源过滤器在过滤器管道中第二个被执行,通常用于请求结果的缓存和短路过滤器管道,通过实现接口 IResourceFilter 或者IAsyncResourceFilter。和其他过滤器一样,实现接口,只是接口不同,接收的参数两类型不同,但是这也正意味着执行的时机不同。接收的参数类型为:`ResourceExecutedContext`。

二、资源过滤器实现
资源过滤器定义:
资过滤器的定义,需要实现接口 IResourceFilter 或者IAsyncResourceFilter,接收的参数类型为:ResourceExecutedContext。
/// <summary>/// 资源过滤器/// </summary>public class MyResourceFilter : Attribute, IResourceFilter//过滤器要继承Attribute 特性,这样我们也可以当做特性使用{/// <summary>/// 内存缓存对象/// </summary>private readonly IMemoryCache _memoryCache;/// <summary>/// 构造注入/// </summary>public MyResourceFilter(IMemoryCache memoryCache){_memoryCache = memoryCache;}/// <summary>/// 资源过滤器过滤器执行之前(befor)/// </summary>/// <param name="context"></param>public void OnResourceExecuted(ResourceExecutedContext context){//针对哪些Action,也可以吧特性标注在Action上var ad = context.ActionDescriptor;var str = ad.RouteValues["controller"] + "/" + ad.RouteValues["action"];if (str != "ResourceFilter/Test"){return;}//我们可以将当前的结果context.Result缓存起来,当执行ing时,直接返回,为了方便示例演示,我们用时间表示。string content = "Action第一次执行调用时间:" + DateTime.Now;var value = _memoryCache.Get("key"); //判断内存中是否有内容,有就直接返回,不再执行action过程。if (value == null){_memoryCache.Set("key", content);}}/// <summary>/// 资源过滤器过滤器执行之后(after)/// </summary>/// <param name="context"></param>public void OnResourceExecuting(ResourceExecutingContext context){//针对哪些Action,也可以吧特性标注在Action上var ad = context.ActionDescriptor;var str = ad.RouteValues["controller"] + "/" + ad.RouteValues["action"];if (str != "ResourceFilter/Test"){return;}var content = _memoryCache.Get("key"); //判断内存中是否有内容,有就直接返回,不再执行action过程。if (content != null){var result = new { IsSuccess = true, Msg= _memoryCache.Get("key") };//短路返回,不会再执行Action中方法和OnResourceExecuted方法context.Result = new ContentResult() { Content = Newtonsoft.Json.JsonConvert.SerializeObject(result) };};}}
添加到全局过滤器:
services.AddMvc(options =>{options.Filters.Add<MyResourceFilter>();});
添加测试Action:
/// <summary>/// 资源过滤器测试/// </summary>public class ResourceFilterController : ControllerBase{/// <summary>/// 内存缓存对象/// </summary>private readonly IMemoryCache _memoryCache;/// <summary>/// 构造注入/// </summary>/// <param name="memoryCache"></param>public ResourceFilterController(IMemoryCache memoryCache){_memoryCache = memoryCache;}/// <summary>/// 资源过滤器测试,获取接口第一次调用时间/// 如果第一次调用Action:会进入Action执行方法体/// 如果不是第一次调用Action:在资源过滤器中直接短路返回第一次调用时间/// </summary>/// <returns></returns>[HttpGet]public ActionResult Test(){string content = "Action第一次执行调用时间:" + DateTime.Now;var value = _memoryCache.Get("key"); //判断内存中是否有内容,有就直接返回,不再执行action过程。if (value == null){_memoryCache.Set("key", content);}return Ok(new { IsSuccess = true, Msg = content });}}
三、验证:
第1次调用:
访问地址:
https://localhost:5001/ResourceFilter/Test
第N次调用:
