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 = new FormUrlEncodedContent(requestDic);

// 生成Request的Message
var httpRequestMessage = new HttpRequestMessage
{
    Method = HttpMethod.Post,	// 请求方式
    RequestUri = new Uri("http://localhost:5000/DateTime/GetTimeStamp"),	// 请求地址
    Content = encodedContent ,	// 请求内容
};

// 在HttpRequestMessage中可以任意的添加请求头
httpRequestMessage.Headers.Add("GitHub", "XgHao");
// 添加签名头
var sign = await GenerateSign(requestTime);
httpRequestMessage.Headers.Add("X-Sign", sign);

// 发送请求
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发出的请求

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值