-NET 中如何選擇 WebClient,HttpClient,HttpWebRequest

當我們在用 .NET 調用 RestAPI 時通常有三種選擇,分別爲:WebClient, HttpWebRequest,HttpClient,這篇文章我們將會討論如何使用這三種方式去調用 RestAPI,我還會提供相應的代碼案例來幫助你更好的理解這三者的概念和使用方式,簡單來說:

接下來我們討論一下抽象類 WebRequest

WebRequest

WebRequest 是一種基於特定的 http 實現, 它是一個抽象類, 所以在處理 Reqeust 請求時底層會根據傳進來的 url 生成相應的子類,如:HttpWebRequest 或 FileWebRequest ,下面的代碼展示瞭如何使用 WebRequest。

WebRequest webRequest = WebRequest.Create(uri);
webRequest.Credentials = CredentialCache.DefaultCredentials;
webRequest.Method ="GET";
HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();

WebRequest 是 .NET Framework 中第一個用來處理 Http 請求的類,在處理 Http請求和響應 方面給調用者提供了諸多的靈活性,你還可以使用這個類來存取 headers, cookies, protocols 和 timeouts 等等,下面的代碼展示了其實現子類 HttpWebRequest 是如何使用的。

HttpWebRequest http = HttpWebRequest)WebRequest.Create(“http://localhost:8900/api/default”);
WebResponse response = http.GetResponse();
MemoryStream memoryStream = response.GetResponseStream();
StreamReader streamReader = new StreamReader(memoryStream);
string data = streamReader.ReadToEnd();

WebClient

WebClient 是 HttpWebRequest 的高層封裝,它給調用者提供了更便捷的使用方式,理所當然做出的犧牲就是 WebClient 的性能略遜於 HttpWebRequest,如果你的業務場景只是簡單訪問第三方的 Http Service,那麼我建議你使用 WebClient ,同理如果你有更多的精細化配置則使用 HttpWebRequest,下面的代碼展示瞭如何使用 WebClient 。

string data = null;

using (var webClient = new WebClient())
{
    data = webClient.DownloadString(url);
}

HttpClient

HttpClient 是在 .NET Framework 4.5 中被引入的,如果你的項目是基於 .NET 4.5 以上版本,除一些特定的原因之外,建議你優先使用 HttpClient,本質上來說,HttpClient 作爲後來之物,它吸取了 HttpWebRequest 的靈活性及 WebClient 的便捷性,所以說 🐟 和 🐻 可兼得。

HttpWebRequest 在 request/response 對象上提供了非常精細化的配置,同時你也要注意 HttpClient 的出現並不是爲了取代 WebClient,言外之意就是 HttpClient 也有缺點,比如說:不能提供 進度處理URI 定製,不支持 FTP 等等,HttpClient 的優點也有很多,它所有關於 IO 操作的方法都是異步的,當然有特殊原因的話也可以使用同步方式,下面的代碼展示瞭如何使用 HttpClient。

public async Task<Author> GetAuthorsAsync(string uri)
{
    Author author = null;
    HttpResponseMessage response = await client.GetAsync(uri);
    if (response.IsSuccessStatusCode)
    {
        author = await response.Content.ReadAsAsync<Author>();
    }
    return author;
}

值得注意的是當 response 出現錯誤時,默認情況下 HttpClient 並不會拋出異常,如果你一定要求 HttpClient 在這種情況下拋出異常,可更改 IsSuccessStatusCode = false 來改變這種默認行爲,做法就是調用 response.EnsureSuccessStatusCode();

public async Task<Author> GetAuthorsAsync(string uri)
{
    Author author = null;

    HttpResponseMessage response = await client.GetAsync(uri);

    response.EnsureSuccessStatusCode();
    
    if (response.IsSuccessStatusCode)
    {
        author = await response.Content.ReadAsAsync<Author>();
    }

    return author;
}

在項目開發中,推薦的做法是保持 HttpClient 的單例化,如果不這麼做的話,每次 Request 請求實例化一次 HttpClient ,那麼大量的請求必將你的 socket 耗盡並拋出 SocketException 異常。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/_DisynLaDScnjXwUFK1XSg