using Microsoft.AspNetCore.Mvc.Filters; using System.Collections.Concurrent; using System.Text.Json; public class ThrottleFilter : IAsyncActionFilter { private static readonly ConcurrentDictionary _lastExecutionTimes = new ConcurrentDictionary(); private readonly int _intervalInSeconds; public ThrottleFilter(int intervalInSeconds) { _intervalInSeconds = intervalInSeconds; } public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var actionName = context.ActionDescriptor.DisplayName; var parameterString = GenerateParameterString(context.ActionArguments); var key = $"{actionName}_{parameterString}"; if (_lastExecutionTimes.TryGetValue(key, out var lastExecutionTime)) { var elapsedTime = DateTime.Now - lastExecutionTime; if (elapsedTime.TotalSeconds < _intervalInSeconds) { context.Result = new OkObjectResult(new WebResponseContent().Error("请求过于频繁,请稍后再试")); return; } } _lastExecutionTimes[key] = DateTime.Now; await next(); } private string GenerateParameterString(IDictionary arguments) { if (arguments == null || arguments.Count == 0) { return ""; } var paramStrings = new List(); foreach (var argument in arguments) { var key = argument.Key; var value = argument.Value; string valueString; if (value == null) { valueString = "null"; } else if (IsSimpleType(value.GetType())) { valueString = value.ToString(); } else { valueString = JsonSerializer.Serialize(value); } paramStrings.Add($"{key}={valueString}"); } return string.Join("&", paramStrings); } // 判断类型是否为简单类型 private bool IsSimpleType(Type type) { return type.IsPrimitive || type == typeof(string) || type == typeof(decimal); } }