简单实现接口幂等性,根据参数的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. Java安全之ClassLoader

    Java安全之ClassLoader 类加载机制 Java中的源码.java后缀文件会在运行前被编译成.class后缀文件,文件内的字节码的本质就是一个字节数组 ,它有特定的复杂的内部格式,Java类 ...

  2. P6624-[省选联考2020A卷]作业题【矩阵树定理,欧拉反演】

    正题 题目链接:https://www.luogu.com.cn/problem/P6624 题目大意 \(n\)个点的一张图,每条边有权值,一棵生成树的权值是所有边权和乘上边权的\(gcd\),即 ...

  3. Javascript 常见的高阶函数

    高阶函数,英文叫 Higher Order function.一个函数可以接收另外一个函数作为参数,这种函数就叫做高阶函数. 示例: function add(x, y, f) { return f( ...

  4. Visual Studio Code (VSCode) 配置 C/C++ 开发编译环境

    前言 工作多年,突然发现很多C++的基础都忘记了,加之C++不断更新换代后的各种新特性,于是想重拾C++的基础学习.虽然现在工作都是Linux平台,但考虑到个人方便,自己也仅仅想重温语法,家里家外都可 ...

  5. apiserver源码分析——处理请求

    前言 上一篇说道k8s-apiserver如何启动,本篇则介绍apiserver启动后,接收到客户端请求的处理流程.如下图所示 认证与授权一般系统都会使用到,认证是鉴别访问apiserver的请求方是 ...

  6. MyBatis 面试复习整理

    MyBatis MyBatis 是一款优秀的ORM(对象关系映射)框架,可以通过对象和数据库之间的映射,将程序中的对象自动存储到数据库中.它内部封装了 JDBC ,使开发者只需要关注 SQL语句本身, ...

  7. 【死磕NIO】— 阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,这你真的分的清楚吗?

    通过上篇文章([死磕NIO]- 阻塞.非阻塞.同步.异步,傻傻分不清楚),我想你应该能够区分了什么是阻塞.非阻塞.异步.非异步了,这篇文章我们来彻底弄清楚什么是阻塞IO,非阻塞IO,IO复用,信号驱动 ...

  8. vue-devtools 安装

    vue火了很久了,但是一直赶不上时代步伐的我今天才开始学,首先,根据vue官网介绍,推荐安装Vue Devtools.它允许你在一个更友好的界面中审查和调试 Vue 应用. 首先,将vue-devto ...

  9. Serverless 是一种思想状态

    来源 | Serverless 公众号:作者 | Ben Kehoe:译者 | donghui 函数不是重点 如果你因为喜欢 Lambda 而选择 Serverless,你这样做的原因是错误的.如果你 ...

  10. java课堂测试3第一部分(未完善)

    package test3;import java.util.*; public class Grade2 { static String[][] mis=new String[500][4]; // ...