情景描述
将一个时间转换为对应的unix时间戳,
字符集使用UTF-8编码,数据通讯统一采用 HTTP 协议通讯,使用POST 方法请求并传递参数。
POST请求Content-Type 设置为application/x-www-form-urlencoded
除此之外,我们对请求添加签名的校验,key设置为X-Sign
接口定义
////// 获取时间戳(毫秒). /// /// ///[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(); }
其中入参定义
////// 自定义时间类. /// public class MyDateTime { ////// 年. /// public int Year { get; set; } ////// 月. /// public int Month { get; set; } ////// 日. /// public int Day { get; set; } ////// 时. /// public int Hour { get; set; } ////// 分. /// public int Minute { get; set; } ////// 秒. /// public int Second { get; set; } }
签名方法
签名的话,我们简单的把入参做keyValue处理,这里对key进行排序,然后返回MD5加密后的结果就行了
////// 生成签名. /// /// ///private async Task GenerateSign(MyDateTime dateTime) { // 利用反射获取属性及对应的值,根据key的Name排序 var properties = dateTime.GetType().GetProperties().OrderBy(e => e.Name); // 使用一个字典来存放 var signDic = new Dictionary (); 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();
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发出的请求
以上这篇C# 使用HttpClient模拟请求的案例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持考高分网。



