1. 程式人生 > 程式設計 >C# 使用HttpClient模擬請求的案例

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,還有計算返回的時間戳。

C# 使用HttpClient模擬請求的案例

切換到WebForms可以看到請求的引數

C# 使用HttpClient模擬請求的案例

說明使用HttpClient傳送請求成功了。

如果Fiddler沒能捕獲請求,請考慮設定HttpClient的代理,具體參考這篇文章C# 如何使用Fiddler捕獲本地HttpClient發出的請求

以上這篇C# 使用HttpClient模擬請求的案例就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。