C# 使用HttpClient模拟请求的案例

作者:丨背水丨 时间:2023-10-16 18:20:14 

情景描述

将一个时间转换为对应的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,还有计算返回的时间戳。

C# 使用HttpClient模拟请求的案例

切换到WebForms可以看到请求的参数

C# 使用HttpClient模拟请求的案例

说明使用HttpClient发送请求成功了。

如果Fiddler没能捕获请求,请考虑设置HttpClient的代理,具体参考这篇文章C# 如何使用Fiddler捕获本地HttpClient发出的请求

来源:https://blog.csdn.net/ZUFE_ZXh/article/details/108595975

标签:C#,HttpClient,请求
0
投稿

猜你喜欢

  • 详解spring cloud Feign使用中遇到的问题总结

    2023-12-13 19:03:48
  • SpringMVC入门实例

    2023-02-04 12:43:48
  • c# 动态构建LINQ查询表达式

    2022-03-23 20:40:47
  • 简述IDEA集成Git在实际项目中的运用

    2022-06-30 20:43:05
  • Android自定义View控件实现刷新效果

    2022-05-12 14:43:22
  • Android自定义View实现微信语音界面

    2022-03-27 20:35:27
  • 仿iphone中短信以及通话记录的时间显示

    2021-07-23 02:34:28
  • DataTables List互相转换的实现类示例

    2023-04-06 07:24:05
  • C# 填充Excel图表、图例背景色的实例代码

    2023-08-06 04:01:31
  • 如何使用SpEL表达式实现动态分表查询

    2022-01-05 03:09:55
  • Spring Boot整合Redis的完整步骤

    2023-06-03 03:21:56
  • Java重写equals及hashcode方法流程解析

    2023-10-14 06:53:13
  • 新手了解java IO基础知识

    2023-10-20 22:19:45
  • Spring+MyBatis实现数据读写分离的实例代码

    2021-08-31 04:34:48
  • c#动态加载卸载DLL的方法

    2023-06-08 08:18:08
  • winform壁纸工具为图片添加当前月的日历信息

    2022-03-05 07:23:01
  • Unity自定义编辑器界面(Inspector界面)

    2023-01-09 08:40:46
  • Repeater中添加按钮实现点击按钮获取某一行数据的方法

    2022-05-17 08:19:31
  • 详解直接插入排序算法与相关的Java版代码实现

    2022-06-13 09:06:38
  • RabbitMQ消息中间件示例详解

    2021-12-10 23:09:58
  • asp之家 软件编程 m.aspxhome.com