| | |
| | | using Microsoft.AspNetCore.Mvc.Filters; |
| | | using System.Collections.Concurrent; |
| | | using System.Text.Json; |
| | | |
| | | public class ThrottleFilter : IAsyncActionFilter |
| | | { |
| | |
| | | public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) |
| | | { |
| | | var actionName = context.ActionDescriptor.DisplayName; |
| | | if (_lastExecutionTimes.TryGetValue(actionName, out var lastExecutionTime)) |
| | | |
| | | 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) |
| | |
| | | } |
| | | } |
| | | |
| | | _lastExecutionTimes[actionName] = DateTime.Now; |
| | | _lastExecutionTimes[key] = DateTime.Now; |
| | | await next(); |
| | | } |
| | | |
| | | private string GenerateParameterString(IDictionary<string, object> arguments) |
| | | { |
| | | if (arguments == null || arguments.Count == 0) |
| | | { |
| | | return ""; |
| | | } |
| | | |
| | | var paramStrings = new List<string>(); |
| | | 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); |
| | | } |
| | | } |