基于前面对Action Filter的介绍,本节通过实例来说明其用法。
Action Filter可以在满足条件的时候终止操作方法的执行。
在Action Filter中,如果我们不调用 await next(),就可以终止Action方法的执行了。
为了避免客户端恶意发送大量请求消耗服务器资源,实现“一秒钟内同一个IP地址只允许访问一次”
1.自定义类RateLimitActionFilter,实现接口IAsyncActionFilter。
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace WebApiActionFilter
{
public class RateLimitActionFilter : IAsyncActionFilter
{
private readonly IMemoryCache memCache;
public RateLimitActionFilter(IMemoryCache memCache)
{
this.memCache = memCache;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
Console.WriteLine("RateLimitActionFilter 执行action前");
string ip = context.HttpContext.Connection.RemoteIpAddress.ToString();
string cacheKey = $"lastvisittick_{ip}";
long? lastVisit = memCache.Get<long?>(cacheKey);
if (lastVisit == null || Environment.TickCount64 - lastVisit > 1000) // Environment.TickCount64 系统时间
{
memCache.Set(cacheKey, Environment.TickCount64, TimeSpan.FromSeconds(10));//避免长期不访问的用户,占据缓存的内存
await next();
Console.WriteLine("RateLimitActionFilter 执行action后");
}
else
{
ObjectResult result = new ObjectResult("访问太频繁")
{
StatusCode = 429
};
context.Result = result;
}
}
}
}
2.将自定义的过滤器进行注入。
第一次访问时:
连续访问时:
如果是频繁访问,那么就不会再执行action方法,使用过滤器起到了限流访问的目的。