C# 使用HttpClient模拟请求的案例
作者:丨背水丨 发布时间:2023-10-16 18:20:14
标签:C#,HttpClient,请求
情景描述
将一个时间转换为对应的unix时间戳,
字符集使用UTF-8编码,数据通讯统一采用 HTTP 协议通讯,使用POST 方法请求并传递参数。
POST请求Content-Type 设置为application/x-www-form-urlencoded
除此之外,我们对请求添加签名的校验,key设置为X-Sign
接口定义
/// <summary>
/// 获取时间戳(毫秒).
/// </summary>
/// <param name="dateTime"></param>
/// <returns></returns>
[HttpPost]
[AllowAnonymous]
[Route("DateTime/GetTimeStamp")]
public string GetTimeStamp([Required] MyDateTime dateTime)
{
// 没有签名或者签名不匹配返回null.
if (!Request.Headers.TryGetValue("X-Sign", out var xSign) || GenerateSign(dateTime) != xSign)
{
return $"签名{xSign}验证失败";
}
// 返回时间戳
var time = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second);
return ((time.ToUniversalTime().Ticks - 621355968000000000) / 1000).ToString();
}
其中入参定义
/// <summary>
/// 自定义时间类.
/// </summary>
public class MyDateTime
{
/// <summary>
/// 年.
/// </summary>
public int Year { get; set; }
/// <summary>
/// 月.
/// </summary>
public int Month { get; set; }
/// <summary>
/// 日.
/// </summary>
public int Day { get; set; }
/// <summary>
/// 时.
/// </summary>
public int Hour { get; set; }
/// <summary>
/// 分.
/// </summary>
public int Minute { get; set; }
/// <summary>
/// 秒.
/// </summary>
public int Second { get; set; }
}
签名方法
签名的话,我们简单的把入参做keyValue处理,这里对key进行排序,然后返回MD5加密后的结果就行了
/// <summary>
/// 生成签名.
/// </summary>
/// <param name="dateTime"></param>
/// <returns></returns>
private async Task<string> GenerateSign(MyDateTime dateTime)
{
// 利用反射获取属性及对应的值,根据key的Name排序
var properties = dateTime.GetType().GetProperties().OrderBy(e => e.Name);
// 使用一个字典来存放
var signDic = new Dictionary<string, string>();
foreach (var property in properties)
{
var key = property.Name;
var value = property.GetValue(dateTime)?.ToString();
signDic.Add(key, value);
}
// 用UrlEncoded处理
var sign = await new FormUrlEncodedContent(signDic).ReadAsStringAsync().ConfigureAwait(false);
// 返回MD5加密后的结果
return Convert.ToBase64String(new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(sign)));
}
使用HttpClient模拟请求
// 创建HttpClient实例
var httpClient = new HttpClient();
// 请求的时间,2020-10-01 08:10:30
var requestTime = new MyDateTime
{
Year = 2020,
Month = 10,
Day = 1,
Hour = 8,
Minute = 10,
Second = 30,
};
// 设置HttpRequestMessage中的Content。
// 请求入参,我们接口定义的入参是dateTime,所以这里的Key也是dateTime
var requestDic = new Dictionary<string, string>();
requestDic.Add("dateTime", JsonConvert.SerializeObject(requestTime));
var encodedContent = await new FormUrlEncodedContent(requestDic).ReadAsStringAsync().ConfigureAwait(false);
var httpContent = new StringContent(encodedContent, Encoding.UTF8, "application/x-www-form-urlencoded");
// 添加签名头
var sign = await GenerateSign(requestTime);
httpContent.Headers.Add("X-Sign", sign);
// 生成Request的Message
var httpRequestMessage = new HttpRequestMessage
{
Method = HttpMethod.Post, // 请求方式
RequestUri = new Uri("http://localhost:5000/DateTime/GetTimeStamp"), // 请求地址
Content = httpContent, // 请求内容
};
// 在HttpRequestMessage中可以任意的添加请求头
httpRequestMessage.Headers.Add("GitHub", "XgHao");
// 发送请求
var response = await httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false);
var timeStamp = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
捕获请求
这里我们使用Fiddler来捕获请求
可以看到,我们的签名及我们自己加的其他Header,还有计算返回的时间戳。
切换到WebForms可以看到请求的参数
说明使用HttpClient发送请求成功了。
如果Fiddler没能捕获请求,请考虑设置HttpClient的代理,具体参考这篇文章C# 如何使用Fiddler捕获本地HttpClient发出的请求
来源:https://blog.csdn.net/ZUFE_ZXh/article/details/108595975
0
投稿
猜你喜欢
- 一、前提准备安装R软件,需要安装32位的R软件,64位的调用会报错。另外就是讲R添加到电脑环境变量中。打开R软件,安装包 scatterpl
- 前言WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏
- 本文介绍了Flutter 通过Clipper实现各种自定义形状的示例代码,分享给大家,具体如下:ClipOval 圆形裁剪ClipOval(
- 本文实例讲述了Java基于命令模式实现邮局发信功能。分享给大家供大家参考,具体如下:一. 模式定义命令模式,将来自客户端的请求封建为一个对象
- 有时候你可能需要通过代码来控制执行linux命令实现某些功能。针对这类问题可以使用JSCH来实现,具体代码如下:public class C
- timer和timertask是jdk自带的定时任务实现,无需导入第三方jar包来完成1、指定多久之后执行此任务,注意:只会执行一次publ
- Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动
- package dao;import java.sql.*;public class BaseDao { //oracle//&n
- Object类型是所有类型的基类,其下面有ValueType类型。什么结构啊,枚举啊,都继承ValueType,这些都是值类型。其他的什么类
- 在某些业务场景中,我们只需要业务代码中定义相应的接口或者相应的注解,并不需要实现对应的逻辑。比如 mybatis和feign: 在 myba
- 定义在一幅无向图G=(V,E) 中,(u,v) 为连接顶点u和顶点v的边,w(u,v)为边的权重,若存在边的子集T&am
- 本篇主要描述“发送邮箱验证码、session校验”相关前(html\js)后(java)台代码,业务逻辑示例,闲话少诉,直接上代码。1、引入
- MyBatis-Spring允许你在Service Bean中注入映射器。当使用映射器时,就像调用DAO那样来调用映射器就可以了,但是此时你
- 本文介绍了如何使用Spring Security OAuth2构建一个授权服务器来验证用户身份以提供access_token,并使用这个ac
- 这里介绍一个简易的音乐播放器,供大家参考,具体内容如下效果图如下:但是,由于这是一个简易版的音乐播放器,所播放的音乐只有一首,且被写死,但,
- 一致性哈希节点的增加和减少,大部分节点的 Hash一致package consistenthashimport ("hash/cr
- Mybatis-Spring当我们使用mybatis和spring整合后为什么下面的代码可以运行?一个问题:我就写了个mapper接口为什么
- Java 编程语言中时间的处理类有 Date类与 Calendar类。目前官方不推荐使用 Date类,因为其不利于国际化;而是推荐使用 Ca
- 1. Spring 是什么我们通常所说的 Spring 指的是 Spring Framework(Spring 框架),它是一个开源框架,有
- httpSecurity类似于spring security的xml配置文件命名空间配置中的<http>元素。它允许对特定的ht