using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Net; using System.Text; using WMS.Web.Core.Internal.Results; using WMS.Web.Domain.Services.Public; using Microsoft.AspNetCore.Http; using Newtonsoft.Json; using System.IO; using System.Threading.Tasks; namespace WMS.Web.Repositories.DependencyInjection { /// /// 防重复提交 /// public class PlatformActionMiddleware { private readonly RequestDelegate next; private readonly ILogger _logger; private readonly RedisClientService _redisClientService; /// /// 统一错误处理中间件 /// public PlatformActionMiddleware(RequestDelegate next, ILogger logger, RedisClientService redisClientService) { this.next = next; _logger = logger; _redisClientService = redisClientService; } private string bodyStr = ""; /// /// 激活 /// /// /// public async Task Invoke(HttpContext context) { //默认 请求body只能读取一次 所以在这里需要手动把他设置成读取多次 并且 不能使用using 释放 context.Request.EnableBuffering(); StreamReader requestReader = new StreamReader(context.Request.Body, Encoding.UTF8); bodyStr = await requestReader.ReadToEndAsync(); context.Request.Body.Seek(0, SeekOrigin.Begin); string httpMethod = WebUtility.HtmlEncode(context.Request.Method); if (httpMethod == "POST") { //使用请求路径作为唯一key string path = context.Request.Path; string authorization = context.Request.Headers["Authorization"]; string cacheToken = $"{authorization}_{path}"; string keyValue = string.IsNullOrEmpty(bodyStr) ? "yc" : bodyStr; if (path != null) { //var cache = iZen.Utils.Core.iCache.CacheManager.GetCacheValue(cacheToken); string cv = _redisClientService.GetStringKey(cacheToken); if (cv == null && bodyStr != cv) { //iZen.Utils.Core.iCache.CacheManager.SetChacheValueSeconds(cacheToken, keyValue, 1); //设置缓存10秒过期 _redisClientService.SetStringKey(cacheToken, keyValue, TimeSpan.FromSeconds(10)); } else { context.Response.StatusCode = 200; var result = JsonConvert.SerializeObject(new { status = 888888, data = string.Empty, message = "重复提交" }); context.Response.ContentType = "application/json;charset=utf-8"; await context.Response.WriteAsync(result); return; } } } await next(context); } } }