.net core api 请求实现接口幂等性
简单实现接口幂等性,根据参数的hascode实现:
- 参数介绍
- WaitMillisecond : 请求等待毫秒数
- CacheMillisecond:请求结果缓存毫秒数
- 参数具体使用场景
- WaitMillisecond :用户频繁发起多次请求,只处理第一次请求,后续请求在这个等待(时间范围内)的均返回“正在执行..”,超出这个预设时间会再次真实请求到后台业务逻辑
- CacheMillisecond:第一次请求成功并且拿到结果,用户频繁发起请求 在这个缓存时间在,将返回上次一样的结果。直至过期
1.使用方式
[HttpPost]
[HttpIdempotent(WaitMillisecond = 10000,CacheMillisecond = 3000)]
public async Task<IActionResult> Order(string orderNo)
{
//TODO
}
2.具体实现
1 /// <summary>
2 /// api request idempotence
3 /// </summary>
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 /// <summary>
35 /// http request parameter code collect
36 /// </summary>
37 private static readonly Dictionary<int, HashtableData> HashTable = new();
38
39 /// <summary>
40 /// http request parameter code
41 /// </summary>
42 public int _httpHasCode;
43
44 /// <summary>
45 /// waiting for the last request , default value:1000
46 /// </summary>
47 public double WaitMillisecond { get; set; } = 1000;
48
49 /// <summary>
50 /// result cache Millisecond , default value:1000
51 /// </summary>
52 public double CacheMillisecond { get; set; } = 1000;
53
54 /// <summary>
55 /// interceptor
56 /// </summary>
57 /// <param name="context"></param>
58 /// <param name="next"></param>
59 /// <returns></returns>
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 /// <summary>
113 /// get http request parameter code
114 /// </summary>
115 /// <returns></returns>
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 /// <summary>
145 /// Hashtable parameter model
146 /// </summary>
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 请求实现接口幂等性的更多相关文章
- 防盗链&CSRF&API接口幂等性设计
防盗链技术 CSRF(模拟请求) 分析防止伪造Token请求攻击 互联网API接口幂等性设计 忘记密码漏洞分析 1.Http请求防盗链 什么是防盗链 比如A网站有一张图片,被B网站直接通过img标签属 ...
- Spring中统一相同版本的api请求路径的一些思考
Spring中统一相同版本的api请求路径的一些思考 问题场景 当我们在实际开发中,可能会遇到开发相同同版本的api, 假设相同版本的api请求路径为/v1/functionA,/v1/functio ...
- asp.net core mvc基于Redis实现分布式锁,C# WebApi接口防止高并发重复请求,分布式锁的接口幂等性实现
使用背景:在使用app或者pc网页时,可能由于网络原因,api接口可能被前端调用一个接口重复2次的情况,但是请求内容是一样的.这样在同一个短暂的时间内,就会有两个相同请求,而程序只希望处理第一个请求, ...
- API接口幂等性框架设计
表单重复提价问题 rpc远程调用时候 发生网络延迟 可能有重试机制 MQ消费者幂等(保证唯一)一样 解决方案: token 令牌 保证唯一的并且是临时的 过一段时间失效 分布式: redis+to ...
- 【从零开始搭建自己的.NET Core Api框架】(四)实战!带你半个小时实现接口的JWT授权验证
系列目录 一. 创建项目并集成swagger 1.1 创建 1.2 完善 二. 搭建项目整体架构 三. 集成轻量级ORM框架——SqlSugar 3.1 搭建环境 3.2 实战篇:利用SqlSuga ...
- 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 ...
- .NET CORE API 使用Postman中Post请求获取不到传参问题
开发中遇到个坑 记录下. 使用Postman请求core api 接口时,按之前的使用方法(form-data , x-www-form-urlencoded)怎么设置都无法访问. 最后采用raw写入 ...
- IdentityServer4实现.Net Core API接口权限认证(快速入门)
什么是IdentityServer4 官方解释:IdentityServer4是基于ASP.NET Core实现的认证和授权框架,是对OpenID Connect和OAuth 2.0协议的实现. 通俗 ...
- 详解ASP.NET Core API 的Get和Post请求使用方式
上一篇文章帮助大家解决问题不彻底导致博友使用的时候还是遇到一些问题,欢迎一起讨论.所以下面重点详细讲解我们常用的Get和Post请求( 以.net core2.2的Http[Verb]为方向 ,推荐该 ...
随机推荐
- 『Python』matplotlib初识
1. 核心原理 使用matplotlib绘图的原理,主要就是理解figure(画布).axes(坐标系).axis(坐标轴)三者之间的关系. 下面这幅图更详细: 以"美院学生张三写生画画&q ...
- centos7 .net core 使用supervisor守护进程后台运行
安装supervisor yum install supervisor 配置supervisor vi /etc/supervisord.conf 拉到最后,这里的意思是 /etc/superviso ...
- P7276-送给好友的礼物【dp】
正题 题目链接:https://www.luogu.com.cn/problem/P7276?contestId=39577 题目大意 \(n\)个点的一棵树,\(k\)个关键点,两个人从根出发分别走 ...
- CF461D-Appleman and Complicated Task【并查集】
正题 题目链接:https://www.luogu.com.cn/problem/CF461D 题目大意 \(n*n\)的网格需要填上\(x\)或\(o\),其中有\(k\)个格子已经固定,求有多少中 ...
- mybatis plus 一对多,多表联查的使用小记
阅读本博文需要有基础的mybatis以及mybatis plus知识,如果没有建议您了解相关的内容 本项目使用的是springboot构建的,数据库字段命名不严谨仅做演示测试使用,本文不做相关源码的解 ...
- Bert文本分类实践(二):魔改Bert,融合TextCNN的新思路
写在前面 文本分类是nlp中一个非常重要的任务,也是非常适合入坑nlp的第一个完整项目.虽然文本分类看似简单,但里面的门道好多好多,博主水平有限,只能将平时用到的方法和trick在此做个记录和分享 ...
- 《手把手教你》系列技巧篇(二十五)-java+ selenium自动化测试-FluentWait(详细教程)
1.简介 其实今天介绍也讲解的也是一种等待的方法,有些童鞋或者小伙伴们会问宏哥,这也是一种等待方法,为什么不在上一篇文章中竹筒倒豆子一股脑的全部说完,反而又在这里单独写了一篇.那是因为这个比较重要,所 ...
- Java基础之(六):变量、运算符与JavaDoc
变量.常量 一.变量的命名规范 首字母只能以字母(A-Z或者a-z)或者美元符($)或者下划线(_)开头,不能以数字开头,首字母之后只能跟字母(AZ或者az)或者数字,不能跟美元符或者下划线 源码 p ...
- 洛谷2046 NOI2010海拔
QwQ题目太长 这里就不复制了 题目 这个题...算是个比较经典的平面图最小割变成对偶图的最短路了QwQ 首先考虑最小割应该怎么做. 有一个性质,就是每个点的海拔要么是1,要么是0 QwQ不过这个我不 ...
- spoj2 prime1 (区间筛)
给定t组询问,每组询问包括一个l和r,要求\([l,r]\)的素数有哪些 其中\(t \le 10,1 \le l \le r \le 1000000000 , r-l \le 100000\) Qw ...