首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

HttpClient 入門:從 HttpWebRequest 遷移的關鍵差異與 UserAgent 設定技巧

     編輯:關於.NET

.NET 4.5 引入 `System.Net.Http.HttpClient`,設計理念貼近 HTTP 簡潔本質。本文對比 `HttpWebRequest` 與 `HttpClient` 關鍵差異,重點解決 `UserAgent` 設定無屬性的問題。

HttpWebRequest 時代的 UserAgent 設定

var request = (HttpWebRequest)WebRequest.Create(url);
request.UserAgent = "CNBlogs"; // 直接屬性

HttpClient 的 UserAgent 陷阱

var client = new HttpClient();
// client.UserAgent = "CNBlogs"; // 編譯錯誤:無此屬性

// 發現 DefaultRequestHeaders.UserAgent 僅有 getter
// client.DefaultRequestHeaders.UserAgent // 唯讀集合

正確設定方式

var client = new HttpClient();
client.DefaultRequestHeaders.UserAgent.ParseAdd("CNBlogs/1.0 (+https://example.com)");
// 或
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("CNBlogs", "1.0"));
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("(+https://example.com)"));

`UserAgent` 標頭值為 `ProductInfoHeaderValue` 集合,需用 `ParseAdd` 或 `Add` 方法。

HttpClient 核心優勢

特性HttpWebRequestHttpClient
API 風格同步/APM (Begin/End)Task-based 非同步 (await)
連線管理手動/ConnectionGroup內建連線池、自動重用
標頭操作字串索引器強型別 `HttpRequestHeaders`
內容序列化手動寫入 Stream`HttpContent` 衍生類 (`StringContent`, `FormUrlEncodedContent`, `MultipartFormDataContent`)
可測試性難 (靜態/密封)易 (可 Mock `HttpMessageHandler`)

常見遷移模式對照

// POST Form Data
// HttpWebRequest
var req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
using (var sw = new StreamWriter(req.GetRequestStream()))
    sw.Write("a=1&b=2");

// HttpClient
var client = new HttpClient();
var form = new Dictionary<string,string> {{"a","1"},{"b","2"}};
var response = await client.PostAsync(url, new FormUrlEncodedContent(form));

// POST JSON
// HttpClient
var json = JsonConvert.SerializeObject(model);
var response = await client.PostAsync(url, new StringContent(json, Encoding.UTF8, "application/json"));

// 下載檔案
// HttpClient
using (var stream = await client.GetStreamAsync(url))
using (var file = File.Create(localPath))
    await stream.CopyToAsync(file);

生命週期管理最佳實踐

  • 單例/靜態:`HttpClient` 設計為長壽命、執行緒安全,**全程式單一實例** 或 **DI 註冊 Singleton**
  • 避免 `using (var client = new HttpClient())` 短命建立,導致 `TIME_WAIT` 連接耗盡
  • 需不同 BaseAddress/標頭時,建立多個具名 `HttpClient` (透過 `IHttpClientFactory`)

進階:自訂 HttpMessageHandler

// 記錄請求/回應、重試、熔斷
public class LoggingHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken ct)
    {
        _logger.LogRequest(request);
        var response = await base.SendAsync(request, ct);
        _logger.LogResponse(response);
        return response;
    }
}

// 註冊
var client = new HttpClient(new LoggingHandler(new HttpClientHandler()));

HttpClient 是現代 .NET HTTP 呼叫的標準入口,掌握 `HttpRequestHeaders`、`HttpContent`、`HttpMessageHandler` 三大核心抽象,即可靈活應對各種整合場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved