.net core api 请求实现接口幂等性

简单实现接口幂等性,根据参数的hascode实现:


 

  1.  参数介绍
    1.  WaitMillisecond : 请求等待毫秒数  
    2. CacheMillisecond:请求结果缓存毫秒数
  2. 参数具体使用场景  
    1. WaitMillisecond :用户频繁发起多次请求,只处理第一次请求,后续请求在这个等待(时间范围内)的均返回“正在执行..”,超出这个预设时间会再次真实请求到后台业务逻辑
    2. CacheMillisecond:第一次请求成功并且拿到结果,用户频繁发起请求 在这个缓存时间在,将返回上次一样的结果。直至过期

1.使用方式

        [HttpPost]
        [HttpIdempotent(WaitMillisecond = 10000,CacheMillisecond = 3000)]
        public async Task Order(string orderNo)
     {
        //TODO
     }

2.具体实现

  1     /// 
  2     /// api request idempotence 
  3     /// 
  4     public class HttpIdempotentAttribute : Attribute, IAsyncResourceFilter
  5     {
  6 
  7         static HttpIdempotentAttribute()
  8         {
  9             var thread = new Thread(() =>
 10             {
 11                 while (true)
 12                 {
 13                     var hashtableDatas = HashTable.Where(x => DateTime.Now > x.Value.Time).ToList();
 14 
 15                     if (hashtableDatas.Any())
 16                     {
 17                         foreach (var hashtableData in hashtableDatas)
 18                         {
 19                             HashTable.Remove(hashtableData.Key);
 20                         }
 21                     }
 22                     else
 23                     {
 24                         System.Threading.Thread.Sleep(2000);
 25                     }
 26                 }
 27 
 28             });
 29 
 30             thread.IsBackground = true;
 31             thread.Start();
 32         }
 33 
 34         /// 
 35         /// http request parameter code collect
 36         /// 
 37         private static readonly Dictionary<int, HashtableData> HashTable = new();
 38 
 39         /// 
 40         /// http request parameter code
 41         /// 
 42         public int _httpHasCode;
 43 
 44         /// 
 45         /// waiting for the last request , default value:1000
 46         /// 
 47         public double WaitMillisecond { get; set; } = 1000;
 48 
 49         /// 
 50         /// result cache Millisecond , default value:1000
 51         /// 
 52         public double CacheMillisecond { get; set; } = 1000;
 53 
 54         /// 
 55         /// interceptor
 56         /// 
 57         /// 
 58         /// 
 59         /// 
 60         public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
 61         {
 62             await this.SetHttpParameterHasCode(context.HttpContext);
 63 
 64             if (HashTable.ContainsKey(_httpHasCode))
 65             {
 66                 var hashtableData = (HashtableData)HashTable[_httpHasCode];
 67                 if (hashtableData != null)
 68                 {
 69                     if (DateTime.Now < hashtableData.Time)
 70                     {
 71                         context.Result = hashtableData.Value;
 72                         return;
 73                     }
 74                     else if (DateTime.Now > hashtableData.Time)
 75                     {
 76                         HashTable.Remove(_httpHasCode);
 77                     }
 78                     else if (hashtableData.Value.Value == null)
 79                     {
 80                         context.Result = new ContentResult()
 81                         {
 82                             Content = "正在执行..."
 83                         };
 84                         return;
 85                     }
 86                 }
 87             }
 88 
 89             HashTable.Add(_httpHasCode, new HashtableData(DateTime.Now.AddMilliseconds(WaitMillisecond), null));
 90 
 91             try
 92             {
 93                 var netResult = await next();
 94 
 95                 if (HashTable.ContainsKey(_httpHasCode))
 96                 {
 97                     var hashtableData = (HashtableData)HashTable[_httpHasCode];
 98                     if (hashtableData != null)
 99                     {
100                         hashtableData.Value = (ObjectResult)netResult.Result;
101                         hashtableData.Time = DateTime.Now.AddMilliseconds(CacheMillisecond);
102                     }
103                 }
104             }
105             catch (Exception ex)
106             {
107                 HashTable.Remove(_httpHasCode);
108             }
109 
110         }
111 
112         /// 
113         /// get http request  parameter code
114         /// 
115         /// 
116         private async Task SetHttpParameterHasCode(HttpContext httpContext)
117         {
118 
119             object readFromJson = null;
120 
121             try
122             {
123                 if (httpContext.Request.Method != "GET")
124                 {
125                     readFromJson = await httpContext.Request.ReadFromJsonAsync<object>();
126                 }
127             }
128             catch (Exception e)
129             {
130                 Console.WriteLine(e);
131             }
132 
133             //todo 根据实际项目情况处理,获取Headers toke
134             var authorization = httpContext.Request.Headers["Authorization"];
135 
136             var queryString = httpContext.Request.QueryString;
137             var bodyString = readFromJson == null ? string.Empty : readFromJson.ToString();
138 
139             var builder = $"{authorization}-{queryString}-{bodyString}";
140 
141             this._httpHasCode = builder.GetHashCode();
142         }
143 
144         /// 
145         /// Hashtable parameter model
146         /// 
147         private class HashtableData
148         {
149             public HashtableData(DateTime time, ObjectResult value)
150             {
151                 Time = time;
152                 Value = value;
153             }
154             public DateTime Time { get; set; }
155             public ObjectResult Value { get; set; }
156         }
157     }

 

你可能感兴趣的:(.net core api 请求实现接口幂等性)