.Net Core WebApi 自定义资源过滤器(使用缓存)

在WebApi中想使用缓存,对一些结果集进行缓存,这样可以减小数据库服务器的压力。缓存可以看情况使用,一般缓存经常被查询到并且一般不会更新的数据。

该文章使用MemoryCache来达到缓存数据目的,当然缓存技术有很多种,例如redis,memcache等。

下面用示例说明MemoryCache的用法

1.自定义类CustomResourceFilterAttribute,继承Attribute,并实现接口IResourceFilter

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Caching.Memory;
using System;

namespace MyBlog.WebApi.Utility.FilterUtil
{
    /// <summary>
    /// 自定义资源过滤器 作为特性使用
    /// </summary>
    public class CustomResourceFilterAttribute : Attribute, IResourceFilter
    {
        private IMemoryCache _memoryCache;
        public CustomResourceFilterAttribute(IMemoryCache memoryCache)
        {
            this._memoryCache = memoryCache;
        }

        /// <summary>
        /// 此方法在执行action后被调用
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            string path = context.HttpContext.Request.Path;//api/test/GetCacheTest
            string route = context.HttpContext.Request.QueryString.Value;//?name='11'
            string key = path + route;

            //将路径作为key,结果集作为value放到MemoryCache中,此处的context.Result是指action的返回值
            _memoryCache.Set(key, context.Result);
        }

        /// <summary>
        /// 此方法在执行action前被调用
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            string path = context.HttpContext.Request.Path;//api/test/GetCacheTest
            string route = context.HttpContext.Request.QueryString.Value;//?name='11'
            string key = path + route;

            //检查MemoryCache中是否存在相同的key值,存在则直接从缓存中返回数据;不存在则调用action
            if (_memoryCache.TryGetValue(key, out object value))
            {
                context.Result = value as IActionResult; //执行到此行时,直接返回缓存中的结果,action和OnResourceExecuted都不会被执行
            }
        }


    }
}

自定义一个资源过滤器的类,继承Attribute类,是为了该类可以作为特性在方法中使用;实现IResourceFilter接口,是为了实现资源过滤器的方法,在action执行前后执行自定义的逻辑。

2.在Startup.cs中对MemoryCache进行注入,这里不需要额外引用程序集,因为在新建WebApi项目时,框架已经引入了相关的方法,直接调用即可。

3.在控制器的action中使用缓存

扫描二维码关注公众号,回复: 13511572 查看本文章

        [TypeFilter(typeof(CustomResourceFilterAttribute))]
        [HttpGet("GetCacheTest")]
        public IActionResult GetCacheTest(string strName)
        {
            //模拟从数据库查询数据
            return new JsonResult(new
            {
                name = strName,
                age = 18,
                sex = "男"
            });
        }

下面展示下代码的执行过程:

第一次调用,数据没有被缓存过: 

代码的执行过程:

①先执行过滤器的OnResourceExecuting方法,尝试从缓存中根据key值读取数据,发现缓存中没有对应key值的数据。

②接着执行控制器中的action方法GetCacheTest。

③action执行完毕,获取到数据后执行过滤器的OnResourceExecuted方法,将action返回的数据添加到缓存中。

第二次调用,数据已经在缓存中,查询缓存中的数据: 

代码的执行过程:

①先执行过滤器的OnResourceExecuting方法,尝试从缓存中根据key值读取数据,发现缓存中有对应key值的数据,直接将缓存中的数据返回给调用者。没有执行控制器的action方法,也没有执行过滤器的OnResourceExecuted方法。

缓存的key是由'路径+请求参数'一起组成的一个字符串,只有当路径和请求参数同时变化时,才会重新查询数据库,返回新的数据,并将新的数据添加到缓存中。

也可以设置数据在缓存中的过期时间,当数据过期后,再去缓存中查询就查不到了,这时候就会自动调用action,从数据库查询最新的记录。

为缓存数据设置过期时间:

缓存过期时间的单位可以为:毫秒、秒、分钟、小时、天。

猜你喜欢

转载自blog.csdn.net/liangmengbk/article/details/121732682
今日推荐