翼度科技»论坛 编程开发 .net 查看内容

资源过滤器—MVC中使用资源过滤器实现不执行Action方法体读取缓存信息返回

9

主题

9

帖子

27

积分

新手上路

Rank: 1

积分
27
前言

上两篇文章分享了过滤器实现JWT进行鉴权,分别是通过授权过滤器和操作过滤器实现,这两个过滤器也是最常用的。文章链接:授权过滤器—MVC中使用授权过滤器实现JWT权限认证操作过滤器—MVC中使用操作过滤器实现JWT权限认证,接下来将简单的谈谈资源过滤器在MVC中如何使用,一般项目中这个过滤器很少用到。
一、什么是资源过滤器?

过滤器(Filter)是 AOP(面向切面编程) 思想的一种实现,供我们在执行管道的特定阶段执行代码,通过使用过滤器可以实现短路请求、缓存请求结果、日志统一记录、参数合法性验证、异常统一处理、返回值格式化 等等,同时使业务代码更加简洁单纯,避免很多重复代码。所以在我们的过滤器中,大部分过滤器有开始执行action,即ing 状态的方法,也有action业务代码执行完后触发的ed状态的方法。
资源过滤器在过滤器管道中第二个被执行,通常用于请求结果的缓存和短路过滤器管道,通过实现接口 IResourceFilter 或者IAsyncResourceFilter。和其他过滤器一样,实现接口,只是接口不同,接收的参数两类型不同,但是这也正意味着执行的时机不同。接收的参数类型为:ResourceExecutedContext。

二、资源过滤器实现

资源过滤器定义:

资过滤器的定义,需要实现接口 IResourceFilter 或者IAsyncResourceFilter,接收的参数类型为:ResourceExecutedContext。
  1.    /// <summary>
  2.     /// 资源过滤器
  3.     /// </summary>
  4.     public class MyResourceFilter : Attribute, IResourceFilter//过滤器要继承Attribute 特性,这样我们也可以当做特性使用
  5.     {
  6.         /// <summary>
  7.         /// 内存缓存对象
  8.         /// </summary>
  9.         private readonly IMemoryCache _memoryCache;
  10.         /// <summary>
  11.         /// 构造注入
  12.         /// </summary>
  13.         public MyResourceFilter(IMemoryCache memoryCache)
  14.         {
  15.             _memoryCache = memoryCache;
  16.         }
  17.         /// <summary>
  18.         /// 资源过滤器过滤器执行之前(befor)
  19.         /// </summary>
  20.         /// <param name="context"></param>
  21.         public void OnResourceExecuted(ResourceExecutedContext context)
  22.         {
  23.             //针对哪些Action,也可以吧特性标注在Action上
  24.             var ad = context.ActionDescriptor;
  25.             var str = ad.RouteValues["controller"] + "/" + ad.RouteValues["action"];
  26.             if (str != "ResourceFilter/Test")
  27.             {
  28.                 return;
  29.             }
  30.             //我们可以将当前的结果context.Result缓存起来,当执行ing时,直接返回,为了方便示例演示,我们用时间表示。
  31.             string content = "Action第一次执行调用时间:" + DateTime.Now;
  32.             var value = _memoryCache.Get("key"); //判断内存中是否有内容,有就直接返回,不再执行action过程。
  33.             if (value == null)
  34.             {
  35.                 _memoryCache.Set("key", content);
  36.             }
  37.         }
  38.         /// <summary>
  39.         /// 资源过滤器过滤器执行之后(after)
  40.         /// </summary>
  41.         /// <param name="context"></param>
  42.         public void OnResourceExecuting(ResourceExecutingContext context)
  43.         {
  44.             //针对哪些Action,也可以吧特性标注在Action上
  45.             var ad = context.ActionDescriptor;
  46.             var str = ad.RouteValues["controller"] + "/" + ad.RouteValues["action"];
  47.             if (str != "ResourceFilter/Test")
  48.             {
  49.                 return;
  50.             }
  51.             var content = _memoryCache.Get("key"); //判断内存中是否有内容,有就直接返回,不再执行action过程。
  52.             if (content != null)
  53.             {
  54.                var result = new { IsSuccess = true, Msg= _memoryCache.Get("key") };
  55.                 //短路返回,不会再执行Action中方法和OnResourceExecuted方法
  56.                 context.Result = new ContentResult() { Content = Newtonsoft.Json.JsonConvert.SerializeObject(result) };
  57.             };
  58.             }
  59.         }
复制代码
添加到全局过滤器:
  1.    services.AddMvc(options =>
  2.     {
  3.        options.Filters.Add<MyResourceFilter>();
  4.     });
复制代码
添加测试Action:
  1. /// <summary>
  2.     /// 资源过滤器测试
  3.     /// </summary>
  4.     public class ResourceFilterController : ControllerBase
  5.     {
  6.         /// <summary>
  7.         /// 内存缓存对象
  8.         /// </summary>
  9.         private readonly  IMemoryCache _memoryCache;
  10.         /// <summary>
  11.         /// 构造注入
  12.         /// </summary>
  13.         /// <param name="memoryCache"></param>
  14.         public ResourceFilterController(IMemoryCache memoryCache)
  15.         {
  16.             _memoryCache = memoryCache;
  17.         }
  18.          
  19.         /// <summary>
  20.         /// 资源过滤器测试,获取接口第一次调用时间
  21.         /// 如果第一次调用Action:会进入Action执行方法体
  22.         /// 如果不是第一次调用Action:在资源过滤器中直接短路返回第一次调用时间
  23.         /// </summary>
  24.         /// <returns></returns>
  25.         [HttpGet]
  26.         public ActionResult Test()
  27.         {
  28.             string content = "Action第一次执行调用时间:" + DateTime.Now;
  29.             var value = _memoryCache.Get("key"); //判断内存中是否有内容,有就直接返回,不再执行action过程。
  30.             if (value == null)
  31.             {
  32.                 _memoryCache.Set("key", content);
  33.             }
  34.             return Ok(new { IsSuccess = true, Msg = content });  
  35.         }
  36.     }
复制代码
三、验证:

第1次调用:

访问地址:
  1. https://localhost:5001/ResourceFilter/Test
复制代码

第N次调用:


建群声明:本着技术在于分享,方便大家交流学习的初心,特此建立【编程内功修炼交流群】,热烈欢迎各位爱交流学习的程序员进群,也希望进群的大佬能不吝分享自己遇到的技术问题和学习心得!


来源:https://www.cnblogs.com/wml-it/archive/2023/08/11/17622189.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具