.Net Core ResourceFilter

寻技术 ASP.NET编程 2023年07月10日 75

目录
  • 作用
  • 实现
    • IAsyncResourceFilter
    • IAsyncResourceFilter
  • 全局注册
  • 如何取body参数
  • Aop缓存简单示例
    • 过滤器代码
    • Action代码


作用

  • 在请求Authorize Filter后执行, 可以做缓存处理
  • ResourceFilter 在控制器实例化之前执行
  • ResourceFilter 可以在全局, Controller, Action 都可以设置, 并且都会执行(一个ResourceFilter可以重复设置)

如果都设置执行顺序为

  1. 全局
  2. Controller
  3. Action
  4. Action 方法
  5. Action
  6. Controller
  7. 全局

实现

IAsyncResourceFilter

  1. 需要继承 Attribute 并 并实现 IResourceFilter
  2. 实现接口方法

执行顺序为:

  1. OnResourceExecuting
  2. Action
  3. OnResourceExecuted

IAsyncResourceFilter

  1. 需要继承 Attribute 并 并实现 IAsyncResourceFilter
  2. 实现接口方法
  3. 该接口只提供一个 OnResourceExecutionAsync方法,如果想执行ResourceExecutedContext方法,需要执行方法中ResourceExecutionDelegate委托并取返回值然后代码在执行为ResourceExecutedContext方法

执行顺序为:

  1. OnResourceExecuting
  2. Action
  3. OnResourceExecuted

全局注册

builder.Services.AddControllersWithViews(
    options =>
    {
        //这样注册将对所有action 都生效
        options.Filters.Add<CustomAsyncResourceFilterAttribute>();
    }).AddControllersAsServices();

如何取body参数

参考这个文章

Aop缓存简单示例

过滤器代码

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

namespace Cnpc.Com.Ioc.WebApp.Filter
{
    public class CustomAsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter
    {
        private static Dictionary<string, IActionResult?> cache = new Dictionary<string, IActionResult?>();
        public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
        {
            {
                Console.WriteLine("方法前 Async");
                string user_id = context.HttpContext.Request.Query["User"];
                if (cache.ContainsKey(user_id))
                {
                    context.Result = cache[user_id];
                }
                else
                {
                    ResourceExecutedContext exected = await next();
                    {
                        Console.WriteLine("方法后 Async");
                        cache[user_id] = exected.Result;
                    }
                }
            }

        }
    }
}

Action代码

using Cnpc.Com.Ioc.WebApp.Filter;
using Microsoft.AspNetCore.Mvc;

namespace Cnpc.Com.Ioc.WebApp.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TestFilterController : ControllerBase
    {
        [CustomAsyncResourceFilter]
        [HttpPost]
        public async Task<ActionResult<User?>> LoginIn(string user, string pwd)
        {
            Console.WriteLine("LoginIn");
            await Task.CompletedTask;
            Thread.Sleep(3000);  //测试缓存是否生效,第一次会等3秒, 下一次找到User Action将不会执行
            return new User() { Login = user, Password = pwd };
        }
    }
}
关闭

用微信“扫一扫”