首页 > 其他分享 >资源过滤器—MVC中使用资源过滤器实现不执行Action方法体读取缓存信息返回

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

时间:2023-08-11 09:35:08浏览次数:37  
标签:memoryCache var content Action MVC 过滤器 执行

前言

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

一、什么是资源过滤器?

过滤器(Filter)是 AOP(面向切面编程) 思想的一种实现,供我们在执行管道的特定阶段执行代码,通过使用过滤器可以实现短路请求、缓存请求结果、日志统一记录、参数合法性验证、异常统一处理、返回值格式化 等等,同时使业务代码更加简洁单纯,避免很多重复代码。所以在我们的过滤器中,大部分过滤器有开始执行action,即ing 状态的方法,也有action业务代码执行完后触发的ed状态的方法。

资源过滤器在过滤器管道中第二个被执行,通常用于请求结果的缓存和短路过滤器管道,通过实现接口 IResourceFilter 或者IAsyncResourceFilter。和其他过滤器一样,实现接口,只是接口不同,接收的参数两类型不同,但是这也正意味着执行的时机不同。接收的参数类型为:ResourceExecutedContext
image

二、资源过滤器实现

资源过滤器定义:

资过滤器的定义,需要实现接口 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

image

第N次调用:

image

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

标签:memoryCache,var,content,Action,MVC,过滤器,执行
From: https://www.cnblogs.com/wml-it/p/17622189.html

相关文章

  • 操作过滤器—MVC中使用操作过滤器实现JWT权限认证
    前言上一篇文章分享了授权过滤器实现JWT进行鉴权,文章链接:授权过滤器—MVC中使用授权过滤器实现JWT权限认证,接下来将用操作过滤器实现昨天的JWT鉴权。一、什么是操作过滤器?​与授权过滤器大部分一样,只是执行的时机和继承的接口有所不同。操作过滤器是在Action执行的前和后进......
  • Programming abstractions in C阅读笔记:p91-p106
    《ProgrammingAbstractionsInC》学习第45天,p91-p102,完成第二章内容学习。总结如下:一、技术总结1.垃圾回收p91,"Somelanguage,includingJavasupportasystemfordynamicallocationthatactivelygoesthroughtoseewhatpartsofitareused,freeinganystorageth......
  • Asp.Net Core 之 @Html.Action 迁移
    想必只要接触了netcore的小伙伴们已经发现@html.Action()方法官方已经不提供支持了,转而使用 ViewComponents替代了,同时也增加了TagHelper。但是如果想用以前的@Html.Action()方法,我们其实可以自己动手去实现它。下面就开始实现之旅吧!1、创建静态类 HtmlHelperViewExt......
  • .net6 过滤器、管道模型
    管道处理模型1、[中间件](https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-7.0)可以在典型应用中了解现有中间件的顺序,以及在哪里添加自定义中间件。你可以完全控制如何重新排列现有中间件,或根据场景需要注入新的自定义中间件。......
  • Servlet过滤器
    过滤器的基本概念Servlet过滤器从字面上的字意理解为经过一层次的过滤处理才达到使用的要求,而其实Servlet过滤器就是服务器与客户端请求与响应的中间层组件,在实际项目开发中Servlet过滤器主要用于对浏览器的请求进行过滤处理,将过滤后的请求再转给下一个资源。Filter是在......
  • Programming abstractions in C阅读笔记:p88-p90
    《ProgrammingAbstractionsInC》学习第44天,p88-p90总结。一、技术总结1.内存分配内存分配可以分为:staticallocation、automaticallocation、dynamicallocation。内存分配使用的函数为:malloc()。二、英语总结1."up to this point"是什么意思?答:point: a particular......
  • spring-mvc 系列:拦截器和异常处理器
    目录一、拦截器的配置二、拦截器的三个抽象方法三、多个拦截器的执行顺序四、基于配置的异常处理器五、基于注解的异常处理器一、拦截器的配置SpringMVC中的拦截器用于拦截控制器方法的执行SpringMVC中的拦截器需要实现HandlerInterceptorSpringMVC的拦截器必须在SpringMVC的......
  • 扩展SpringMVC框架的消息转化器
    1、消息转化器请求和响应都有对应的body,而这个body就是需要关注的主要数据。请求体与请求的查询参数或者表单参数是不同的,请求体的表述一般就是一段字符串,而查询参数可以看作url的一部分,这两个是位于请求报文的不同地方。表单参数可以按照一定格式放在请求体中,也可以放在url上......
  • SpringMVC支持跨域访问详解
    跨站HTTP请求(Cross-siteHTTPrequest)是指发起请求的资源所在域不同于该请求所指向资源所在的域的HTTP请求。这里有域名的不同,端口号的不同。很多浏览器在发起跨域访问时是会询问用户是否需要发送该请求,或者干脆不发送跨域访问请求。(最好的办法是不使用ajax之类的,不要在前端......
  • RR有幻读问题吗?MVCC能否解决幻读?
    幻读是MySQL中一个非常普遍,且面试中经常被问到的问题,如果你还搞不懂什么是幻读?什么是MVCC?以及MySQL中的锁?那么请好好收藏和阅读本篇文章,因为它非常重要。RR隔离级别在MySQL中,RR代表RepeatableRead(可重复读),是数据库事务隔离级别中的一种,它的特性是保证同一个事务中,多......