一、简介
在.net core 中Filter
分为以下六大类:
1、AuthorizeAttribute
(权限验证)
2、IResourceFilter
(资源缓存)
3、IActionFilter
(执行方法前后的记录)
4、IResultFilter
(结果生成前后扩展)
5、IAlwaysRun
(响应结果的补充)
6、IExceptionFilter
(异常处理)
二、IResourceFilter
(同步资源缓存)
1、定义Filter
public class CustomerResourceFilterAttribute : Attribute, IResourceFilter
{
private static Dictionary<string,object> cacheDic=new Dictionary<string, object>();
public void OnResourceExecuting(ResourceExecutingContext context)
{
var path=context.HttpContext.Request.Path;
if (cacheDic.ContainsKey(path))
{
context.Result = (IActionResult)cacheDic[path];
}
Console.WriteLine("CustomerResourceFilterAttribute.OnResourceExecuting");
}
public void OnResourceExecuted(ResourceExecutedContext context)
{
var path = context.HttpContext.Request.Path;
cacheDic[path] = context.Result;
Console.WriteLine("CustomerResourceFilterAttribute.OnResourceExecuted");
}
}
2、使用Filter
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
Console.WriteLine($"执行 {this.GetType().Name} 构造函数");
}
[CustomerResourceFilter]
public IActionResult Index()
{
ViewBag.Data = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
return View();
}
}
3、前端页面代码
@{
ViewData["Title"] = "Home Page";
}
<h3>来自于控制器的结果:@ViewBag.Data</h3>
<h3>来自于页面的结果:@DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")</h3>
4、页面效果
按F5可以看到页面值的变化效果,"来自于控制器的结果"的值会一直不变,“来自于页面的结果”随着页面刷新,值会一直变化
三、IAsyncResourceFilter
(异步资源缓存)
public class CustomerAsyncResourceFilterAttribute : Attribute, IAsyncResourceFilter
{
private static Dictionary<string, object> cacheDic = new Dictionary<string, object>();
public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
{
Console.WriteLine("CustomerResourceFilterAttribute.OnResourceExecutionAsync Before");
var path = context.HttpContext.Request.Path;
if (cacheDic.ContainsKey(path))
{
context.Result = (IActionResult)cacheDic[path];
}
else
{
ResourceExecutedContext resource =await next.Invoke();
cacheDic[path] = resource.Result; // 这句话的执行就是去执行控制器的构造函数+Action
Console.WriteLine("CustomerResourceFilterAttribute.OnResourceExecutionAsync After");
}
}
}
四、总结
不管是同步还是异步,他们的执行顺序其实都是一样的,下面是同步和异步分别打印的日志记录:
1、同步日志
2、异步日志
【学习笔记】MVC Core ResourceFilter
(资源过滤器使用)
使用背景:用户请求控制器,资源过滤器根据用户请求的地址,查找对应的缓存,如果找到缓存,则返回结果,如果没有找到,则在后面的过滤器添加动作。
- 创建资源过滤器类,继承并实现
IResourceFilter
- 实现请求进入时的操作。
public void OnResourceExecuted(ResourceExecutedContext context)
{
//结果返回时调用
}
public void OnResourceExecuting(ResourceExecutingContext context)
{
//从缓存读取信息
IMemoryCache cache = context.HttpContext.RequestServices.GetService<IMemoryCache>();
//请求路径作为缓存的Key
string path = context.HttpContext.Request.Path.ToString();
object value = null;
if (cache.TryGetValue(path, out value))
{
string result = value.ToString();
//如果有Result,则不会往执行后面的过滤器
context.Result = new ContentResult() { Content = result };
}
}
- 需要引用的缓存命名空间
using Microsoft.Extensions.DependencyInjection;
- 资源过滤器注册(全局)
services.AddMvc(m=> {
//实例注册方式:每个请求不会重新实例化
//m.Filters.Add(new CacheResourceFilter());
//类型注册方式:每个请求都会重新实例化
m.Filters.Add(typeof(CacheResourceFilter));
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);