.net core webapi教程-IResourceFilter、IAsyncResourceFilter使用详解
深山老妖浏览:5452023-12-02 22:52:08本文累计收益:0我也要赚钱

IResourceFilter、IAsyncResourceFilter两个Filter主要使用场景为数据缓存,如Redis缓存、内存缓存。下面通过实例分别进行讲解。

缓存程序编写思路:

1、定义一个缓存的区域

2、请求来了,根据缓存的标识---判断缓存是否存在,如果有缓存,就返回缓存的值

3、如果没有缓存---做计算

4、计算结果保存到缓存中去
一、IResourceFilter讲解

新建一个类ResourceFilterAttribute继承自Attribute类和 IResourceFilter接口,并且实现IResourceFilter方法,代码如下:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace NetCoreStudy.WebApi.Utility.Filters
{
    public class ResourceFilterAttribute : Attribute, IResourceFilter
    {
        private static Dictionary<string, object> CacheDictionary = new Dictionary<string, object>();
        /// <summary>
        /// 在XX资源之前
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuting(ResourceExecutingContext context)
        {
            string key = context.HttpContext.Request.Path;
            if (CacheDictionary.ContainsKey(key))
            {
                //只要给Reslut赋值了,就会中断往后执行,直接返回给调用方
                context.Result = (IActionResult)CacheDictionary[key];
            }
            Console.WriteLine("在某某资源之前执行");
        }
        /// <summary>
        /// 在XX资源之后
        /// </summary>
        /// <param name="context"></param>
        public void OnResourceExecuted(ResourceExecutedContext context)
        {
            //拿到执行结果,保存到缓存
            string key = context.HttpContext.Request.Path;
            CacheDictionary[key] = context.Result;
            Console.WriteLine("在某某资源之后执行");
        }
    }
}

以上是IResourceFilter用于缓存的实例代码。使用方法需在Action方法上增加[ResourceFilter]特性即可。代码如下:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NetCoreStaty.BussinessInterface;
using NetCoreStudy.Model;
using NetCoreStudy.Utility;
using NetCoreStudy.WebApi.Utility.Filters;

namespace NetCoreStudy.WebApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class FilterController : ControllerBase
    {
        private readonly IBookService _bookService;
        public FilterController(IBookService bookService) {
            _bookService = bookService;
        }
        [HttpGet]
        [ResourceFilter]
        public IActionResult Index()
        {
            var list = _bookService.Query<BookEntity>(c => true).ToList();
            return new JsonResult(new ApiDataResult<List<BookEntity>>()
            {
                Success = true,
                Data = list,
                Message = "图书列表"
            });
        }
    }
}
访问Index方法程序执行流程说明

如访问Index方法,首次访问的代码执行顺序为,先执行Filter的OnResourceExecuting方法,执行完执行控制器的构造方法,构造方法方法执行完执行Index方法,执行完Index方法再执行Filter的OnResourceExecuted方法(将执行结果写入缓存)。之后在访问Index方法的执行顺序是代码只执行Filter的OnResourceExecuting方法就直接返回了(直接将缓存中的数据返回了),后面代码不在执行了。

二、IAsyncResourceFilter讲解

新建一个类AsyncResourceFilterAttribute继承自Attribute类和 IAsyncResourceFilter接口,并且实现IAsyncResourceFilter方法,代码如下:

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace NetCoreStudy.WebApi.Utility.Filters
{
    public class AsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter
    {
        private static Dictionary<string, object> CacheDictionary = new Dictionary<string, object>();
        /// <summary>
        /// 当XX资源执行的时候调用
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
        {
            #region 控制器构造方法及访问的方法执行之前执行的代码
            Console.Write("控制器构造方法及访问的方法执行之前执行的代码");
            string key = context.HttpContext.Request.Path;
            if (CacheDictionary.ContainsKey(key))
            {
                context.Result = (IActionResult)CacheDictionary[key];
            }
            #endregion
            else
            {
                ResourceExecutedContext resource = await next.Invoke();//本行代码去执行执行控制器构造方法及访问的方法
                #region 控制器构造方法及访问的方法执行之后执行的代码
                Console.Write("控制器构造方法及访问的方法执行之后执行的代码");
                CacheDictionary[key] = resource.Result;
                #endregion
            }
        }
    }
}

以上是IAsyncResourceFilter用于缓存的实例代码。使用方法需在Action方法上增加[AsyncResourceFilter]特性即可。代码如下:

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NetCoreStaty.BussinessInterface;
using NetCoreStudy.Model;
using NetCoreStudy.Utility;
using NetCoreStudy.WebApi.Utility.Filters;

namespace NetCoreStudy.WebApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class FilterController : ControllerBase
    {
        private readonly IBookService _bookService;
        public FilterController(IBookService bookService) {
            _bookService = bookService;
        }
        [HttpGet]
        [AsyncResourceFilter]
        public IActionResult AsyncIndex()
        {
            var list = _bookService.Query<BookEntity>(c => true).ToList();
            return new JsonResult(new ApiDataResult<List<BookEntity>>()
            {
                Success = true,
                Data = list,
                Message = "图书列表"
            });
        }
    }
}
访问AsyncIndex方法程序执行流程说明

如访问AsyncIndex方法,首次访问的代码执行顺序为,先执行Filter的如下代码

 #region 控制器构造方法及访问的方法执行之前执行的代码
Console.Write("控制器构造方法及访问的方法执行之前执行的代码");
string key = context.HttpContext.Request.Path;
if (CacheDictionary.ContainsKey(key))
{
     context.Result = (IActionResult)CacheDictionary[key];
}
#endregion

执行完以上代码再执行“ResourceExecutedContext resource = await next.Invoke();”这句代码,执行完再执行控制器的构造方法,构造方法方法执行完执行Index方法,执行完Index方法再执行

#region 控制器构造方法及访问的方法执行之后执行的代码
Console.Write("控制器构造方法及访问的方法执行之后执行的代码");
CacheDictionary[key] = resource.Result;
#endregion

代码将执行结果写入缓存。之后再访问Index方法的执行顺序是代码只执行

 #region 控制器构造方法及访问的方法执行之前执行的代码
Console.Write("控制器构造方法及访问的方法执行之前执行的代码");
string key = context.HttpContext.Request.Path;
if (CacheDictionary.ContainsKey(key))
{
     context.Result = (IActionResult)CacheDictionary[key];
}
#endregion

代码就直接返回了(直接将缓存中的数据返回了),后面代码不在执行了。

以上记录了IResourceFilter、IAsyncResourceFilter使用方法,方便后期项目开发学习使用。

评论列表
发表评论
+ 关注