C# 使用HttpClient模擬請求的案例
阿新 • • 發佈:2020-10-21
情景描述
將一個時間轉換為對應的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發出的請求
以上這篇C# 使用HttpClient模擬請求的案例就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。