Filter

想在大风天去见你,把我吹进你的怀里。 --zhu
切面编程
1、AOP:Aspect Oriented Programming的缩写,意为面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP思想的延续。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2、ASP.NET Core中的Filter的五类:Authorization filter、Resource filter、Action filter、Excption filter、Result filter。
3、所有筛选器一般都有同步,异步两个版本。IActionFilter、IAsyncActionFilter接口。

Excption filter实现
1、当系统中出现未处理异常的时候,我们需要统一给客户端返回响应报文:{"code","500","message","异常信息"}。
2、实现IAsyncExceptionFilter接口。注入IHostEnvironment(判断开发环境还是生产环境)。

ObjectResult result = new ObjectResult (new{code=500,message=message});
result.StatusCode=500;
context.Result=result;
context.ExcptionHandled = true;//是否被处理完成,是则其他ExcptionFilter不会再执行

program.cs代码

builder.Services.Configure<MvcOptions>(options =>
{
  options.Filters.Add<MyExceptionFilter>();
});

Action Filter
1、IAsyncActionFilter接口。
2、多个ActionFilter链式执行。(先进后出)

public class MyActionFilter1 : IAsyncActionFilter
{
  public async Task OnActionExcutionAsync(ActionExcutingContext context,
          ActionExcutionDelegate next)
  {
    Console.WriteLine("MyActionFilter 1:开始执行");
    ActionExcutedContext  r = await next();
    if (r.Exception != null)
      Console.WriteLine("MyActionFilter 1:执行失败");
    else
      Console.WriteLine("MyActionFilter 1:执行成功");
  }
}
 builder.Services.Configure<MvcOptions>(options=>
{
  options.Filters.Add<MyActionFilter1>();
  options.Filters.Add<MyActionFilter2>();
});

无论同步还是异步Action方法,都能用IAsyncActionFilter处理,如果添加两个ActionFilter,运行效果:

(先进后出)

限速ActionFilter
1、Action Filter可以在满足条件时终止方法执行。
2、如果我们不调用await next(),就可以终止Action方法执行。
3、为避免客户端恶意频繁发送大量请求,可以实现“一秒内只允许一个IP地址请求一次”。

public class RateLimitFiter : IASyncActionFilter
{
  private readonly IMemoryCache memCache;
  public RateLimitFilter(IMemoryCache memCache);
  {
    this.memCache = memCache;
  }
  public async Task OnActionExcutionAsync(ActionExcutingContext context,
          ActionExcutionDelegate next)
  {
    string removeIP= context.HttpContext.Connection.RemoteIpAddress.ToString();
    string cacheKey = $"LastVisitTick_{removeIP}";
    long? lastTick= memCache.Get<long?>(cacheKey);
    if(lastTick == null || Environment.TickCount64 - lastTick > 1000)
    {
      memCache.Set(cacheKey,Environment.TickCount64,TimeSpan.FromSeconds(10));
      return next();
    }
    else
    {
      context.Result = new ContentResult {StatusCode = 429};
      return Task.CompletedTask;
    }
  }
}
posted @ 2024-07-29 19:56  小脑虎爱学习  阅读(62)  评论(0)    收藏  举报