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


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

1.使用方式

  1. [HttpPost]
  2. [HttpIdempotent(WaitMillisecond = 10000,CacheMillisecond = 3000)]
  3. public async Task<IActionResult> Order(string orderNo)
         {
            //TODO
         }

2.具体实现

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

.net core api 请求实现接口幂等性的更多相关文章

  1. 防盗链&CSRF&API接口幂等性设计

    防盗链技术 CSRF(模拟请求) 分析防止伪造Token请求攻击 互联网API接口幂等性设计 忘记密码漏洞分析 1.Http请求防盗链 什么是防盗链 比如A网站有一张图片,被B网站直接通过img标签属 ...

  2. Spring中统一相同版本的api请求路径的一些思考

    Spring中统一相同版本的api请求路径的一些思考 问题场景 当我们在实际开发中,可能会遇到开发相同同版本的api, 假设相同版本的api请求路径为/v1/functionA,/v1/functio ...

  3. asp.net core mvc基于Redis实现分布式锁,C# WebApi接口防止高并发重复请求,分布式锁的接口幂等性实现

    使用背景:在使用app或者pc网页时,可能由于网络原因,api接口可能被前端调用一个接口重复2次的情况,但是请求内容是一样的.这样在同一个短暂的时间内,就会有两个相同请求,而程序只希望处理第一个请求, ...

  4. API接口幂等性框架设计

    表单重复提价问题 rpc远程调用时候 发生网络延迟  可能有重试机制 MQ消费者幂等(保证唯一)一样 解决方案: token 令牌 保证唯一的并且是临时的  过一段时间失效 分布式: redis+to ...

  5. 【从零开始搭建自己的.NET Core Api框架】(四)实战!带你半个小时实现接口的JWT授权验证

    系列目录 一.  创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...

  6. C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序

    C#中缓存的使用   缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可:  <%@ Outp ...

  7. .NET CORE API 使用Postman中Post请求获取不到传参问题

    开发中遇到个坑 记录下. 使用Postman请求core api 接口时,按之前的使用方法(form-data , x-www-form-urlencoded)怎么设置都无法访问. 最后采用raw写入 ...

  8. IdentityServer4实现.Net Core API接口权限认证(快速入门)

    什么是IdentityServer4 官方解释:IdentityServer4是基于ASP.NET Core实现的认证和授权框架,是对OpenID Connect和OAuth 2.0协议的实现. 通俗 ...

  9. 详解ASP.NET Core API 的Get和Post请求使用方式

    上一篇文章帮助大家解决问题不彻底导致博友使用的时候还是遇到一些问题,欢迎一起讨论.所以下面重点详细讲解我们常用的Get和Post请求( 以.net core2.2的Http[Verb]为方向 ,推荐该 ...

随机推荐

  1. [转载]Samba 4实现windows匿名访问Linux共享!

    SMB(Server Messages Block,信息服务块). 由于NFS(网络文件系统)可以很好的完成Linux与Linux之间的数据共享,因而 Samba较多的用在了Linux与windows ...

  2. HTML 网页开发、CSS 基础语法——十.CSS语法

    CSS代码书写位置 • CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明 1.内联式 ① 内联式简介 •内联式,也被习惯叫做行内式. •书写位置:在 HTML 标签之上的 style 属性 ...

  3. list集合根据字段分组统计转换成map

    前言 表格需要对数据进行统计 代码实现 public Map getUnitStoreSum(String unitId, String billCode) { List store=listUnit ...

  4. 安装SpaCy出现报错:requests.exceptions.ConnectionError: HTTPSConnectionPool(host='raw.githubusercontent.com', port=443):

    内含安装步骤及报错解决:https://www.cnblogs.com/xiaolan-Lin/p/13286885.html

  5. xLua中Lua调用C#

    xLua中Lua调用C# 1.前提 这里使用的是XLua框架,需要提前配置xlua,设置加载器路径: 可以参考之前的Blog:<xlua入门基础>: //调用段,所有的lua代码都写在Lu ...

  6. RabbitMQ的web页面介绍(三)

    一.Virtual Hosts 每一个 RabbitMQ 服务器都能创建虚拟的消息服务器,我们称之为虚拟主机 (virtual host) ,简称为vhost.每一个 vhost 本质上是一个独立的小 ...

  7. Unity——AssetBundle打包工具

    Unity批量打AB包 为了资源热更新,Unity支持将所有资源打包成AssetBundle资源,存放在SteamingAssets文件夹中: 在项目发布之前,需要将所有资源打包成.ab文件,动态加载 ...

  8. HDC 2021 | HMS Core 6.0:连接与通信论坛,为App打造全场景连接体验

    如何在弱网环境下让用户享受无中断沉浸体验? 如何在全场景互联中让多设备交互如丝般顺滑? 如何在无网区域让移动终端发出紧急求助信息? 连接无处不在,连接与体验息息相关!流畅的网络体验已成为应用开发的关键 ...

  9. python常用功能

    1. 获取昨天日期 引入datetime模块 import datetime def getYesterday(): today = datetime.date.today() #返回当前本地日期 # ...

  10. SpringBoot 01 hello world 01

    hello world项目结构: pom中配置的依赖相当于spring boot的可安装插件,需要下载的依赖直接在里边配置. 目前用到的每个注解: 1.主程序中 @SpringBootApplicat ...