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


  1.  参数介绍
    1.  WaitMillisecond : 请求等待毫秒数  
    2. CacheMillisecond:请求结果缓存毫秒数
  2. 参数具体使用场景  
    1. WaitMillisecond :用户频繁发起多次请求,只处理第一次请求,后续请求在这个等待(时间范围内)的均返回“正在执行..”,超出这个预设时间会再次真实请求到后台业务逻辑
    2. 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 请求实现接口幂等性的更多相关文章

  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. [转载]解决虚拟机中Centos7出现错误:Failed to start LSB: Bring up/down networking

    1.执行 service network restart 出现以下错误 Restarting network (via systemctl):  Job for network.service fai ...

  2. Redis多种数据类型以及使用场景

    SDS简单动态字符串 struct sdshdr { // 记录buf数组中已使用字节的数量 // 等于SDS所保存字符串的长度 int len; // 记录buf数组中未使用字节的数量 int fr ...

  3. 国庆七天假 不如来学学Vue-Router

    Vue-Router 基本介绍 Vue-Router是Vue全家桶中至关重要的一个扩展化插件,使用它能够让我们的组件切换更加的方便,更加容易的开发前后端分离项目,目前Vue-Router版本已更新到4 ...

  4. 微信小程序访问豆瓣api报403错误解决方法

    通过豆瓣API可以获取很多电影.书籍的数据信息,今天在调用豆瓣正在上映电影接口的时候报403错误,原因是豆瓣设置了小程序的访问权限.如下: 解决方法是使用代理,将豆瓣API地址换成 https://d ...

  5. Java秘诀!零基础怎样快速学习Java?

    对于零基础想学Java的朋友,其实一开始最应该做的就是定好学习目标和端正学习态度,切记不要三天打鱼两天晒网! 首先你是零基础,现在急需把Java学好,在保证学习质量的同时,用最短的时间学好Java应该 ...

  6. 洛谷1501 Tree II(LCT,路径修改,路经询问)

    这个题是一个经典的维护路径信息的题,对于路径上的修改,我们只需要把对应的链\(split\)上来,然后修改最上面的点就好,注意pushdown的时候的顺序是先乘后加 然后下传乘法标记的时候,记得把对应 ...

  7. bzoj2037 Sue的小球(区间dp,考虑到对未来的贡献)

    ​​​​​​​​​​​​​​大致意思就是现在你要不断的奔跑到不同的地点去接球,每一秒可以移动一个单位长度,而你接到一个球的动作是瞬间的,收益是y[i]-t*v[i] 然后呢,要求分数最高. 起初看这个 ...

  8. SpringBoot入门04-组件扫描ComponetScan

    被扫描的包下面的类如果被下面注解,则被创建加入到IOC中去 @Component:没有明确的角色 @Service:业务层角色 @Repository:持久层角色 @Controller:控制层角色 ...

  9. 重学c#系列——字典(十一)

    前言 重学c#系列继续更新,简单看一下字典的源码. 看源码主要是解释一下江湖中的两个传言: 字典foreach 顺序是字典添加的顺序 字典删除元素后,字典顺序将会改变 正文 那么就从实例化开始看起,这 ...

  10. pandas 取 groupby 后每个分组的前 N 行

    原始数据如下: (图是从 excel 截的,最左1行不是数据,是 excel 自带的行号,为了方便说明截进来的) 除去首行是标题外,有效数据为 28行 x 4列 目前的需求是根据 partition ...