如何選擇 WebClient HttpWebRequest HttpClient ?
本文轉(zhuǎn)載自微信公眾號「碼農(nóng)讀書」,作者碼農(nóng)讀書。轉(zhuǎn)載本文請聯(lián)系碼農(nóng)讀書公眾號。
當(dāng)我們在用 .NET 調(diào)用 RestAPI 時通常有三種選擇,分別為:WebClient, HttpWebRequest,HttpClient,這篇文章我們將會討論如何使用這三種方式去調(diào)用 RestAPI,我還會提供相應(yīng)的代碼案例來幫助你更好的理解這三者的概念和使用方式,簡單來說:
- HttpWebRequest 是一種相對底層的處理 Http request/response 的方式。
- WebClient 提供了對 HttpWebRequest 的高層封裝,來簡化使用者的調(diào)用。
- HttpClient 是一種新的處理 Http request/response 工具包,具有更高的性能。
接下來我們討論一下抽象類 WebRequest。
WebRequest
WebRequest 是一種基于特定的 http 實現(xiàn), 它是一個抽象類, 所以在處理 Reqeust 請求時底層會根據(jù)傳進(jìn)來的 url 生成相應(yīng)的子類,如: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請求和響應(yīng)方面給調(diào)用者提供了諸多的靈活性,你還可以使用這個類來存取 headers, cookies, protocols 和 timeouts 等等,下面的代碼展示了其實現(xiàn)子類 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 的高層封裝,它給調(diào)用者提供了更便捷的使用方式,理所當(dāng)然做出的犧牲就是 WebClient 的性能略遜于 HttpWebRequest,如果你的業(yè)務(wù)場景只是簡單訪問第三方的 Http Service,那么我建議你使用 WebClient ,同理如果你有更多的精細(xì)化配置則使用 HttpWebRequest,下面的代碼展示了如何使用 WebClient 。
- string data = null;
- using (var webClient = new WebClient())
- {
- data = webClient.DownloadString(url);
- }
HttpClient
HttpClient 是在 .NET Framework 4.5 中被引入的,如果你的項目是基于 .NET 4.5 以上版本,除一些特定的原因之外,建議你優(yōu)先使用 HttpClient,本質(zhì)上來說,HttpClient 作為后來之物,它吸取了 HttpWebRequest 的靈活性及 WebClient 的便捷性,所以說和可兼得。
HttpWebRequest 在 request/response 對象上提供了非常精細(xì)化的配置,同時你也要注意 HttpClient 的出現(xiàn)并不是為了取代 WebClient,言外之意就是 HttpClient 也有缺點,比如說:不能提供 進(jìn)度處理 和 URI 定制,不支持 FTP 等等,HttpClient 的優(yōu)點也有很多,它所有關(guān)于 IO 操作的方法都是異步的,當(dāng)然有特殊原因的話也可以使用同步方式,下面的代碼展示了如何使用 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;
- }
值得注意的是當(dāng) response 出現(xiàn)錯誤時,默認(rèn)情況下 HttpClient 并不會拋出異常,如果你一定要求 HttpClient 在這種情況下拋出異常,可更改 IsSuccessStatusCode = false 來改變這種默認(rèn)行為,做法就是調(diào)用 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;
- }
在項目開發(fā)中,推薦的做法是保持 HttpClient 的單例化,如果不這么做的話,每次 Request 請求實例化一次 HttpClient ,那么大量的請求必將你的 socket 耗盡并拋出 SocketException 異常。
譯文鏈接:https://www.infoworld.com/article/3198673/when-to-use-webclient-vs-httpclient-vs-httpwebrequest.html


























