C#中HttpWebRequest、WebClient、HttpClient的使用詳解
HttpWebRequest:
命名空間: System.Net,這是.NET創(chuàng)建者最初開(kāi)發(fā)用于使用HTTP請(qǐng)求的標(biāo)準(zhǔn)類。使用HttpWebRequest可以讓開(kāi)發(fā)者控制請(qǐng)求/響應(yīng)流程的各個(gè)方面,如 timeouts, cookies, headers, protocols。另一個(gè)好處是HttpWebRequest類不會(huì)阻塞UI線程。例如,當(dāng)您從響應(yīng)很慢的API服務(wù)器下載大文件時(shí),您的應(yīng)用程序的UI不會(huì)停止響應(yīng)。HttpWebRequest通常和WebResponse一起使用,一個(gè)發(fā)送請(qǐng)求,一個(gè)獲取數(shù)據(jù)。HttpWebRquest更為底層一些,能夠?qū)φ麄€(gè)訪問(wèn)過(guò)程有個(gè)直觀的認(rèn)識(shí),但同時(shí)也更加復(fù)雜一些。
//POST方法 public static string HttpPost(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; Encoding encoding = Encoding.UTF8; byte[] postData = encoding.GetBytes(postDataStr); request.ContentLength = postData.Length; Stream myRequestStream = request.GetRequestStream(); myRequestStream.Write(postData, 0, postData.Length); myRequestStream.Close(); HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, encoding); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; } //GET方法 public static string HttpGet(string Url, string postDataStr) { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr); request.Method = "GET"; request.ContentType = "text/html;charset=UTF-8"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream myResponseStream = response.GetResponseStream(); StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8")); string retString = myStreamReader.ReadToEnd(); myStreamReader.Close(); myResponseStream.Close(); return retString; }
WebClient:
命名空間System.Net,WebClient是一種更高級(jí)別的抽象,是HttpWebRequest為了簡(jiǎn)化最常見(jiàn)任務(wù)而創(chuàng)建的,使用過(guò)程中你會(huì)發(fā)現(xiàn)他缺少基本的header,timeoust的設(shè)置,不過(guò)這些可以通過(guò)繼承httpwebrequest來(lái)實(shí)現(xiàn)。相對(duì)來(lái)說(shuō),WebClient比WebRequest更加簡(jiǎn)單,它相當(dāng)于封裝了request和response方法,不過(guò)需要說(shuō)明的是,Webclient和WebRequest繼承的是不同類,兩者在繼承上沒(méi)有任何關(guān)系。使用WebClient可能比HttpWebRequest直接使用更慢(大約幾毫秒),但卻更為簡(jiǎn)單,減少了很多細(xì)節(jié),代碼量也比較少。
public class WebClientHelper { public static string DownloadString(string url) { WebClient wc = new WebClient(); //wc.BaseAddress = url; //設(shè)置根目錄 wc.Encoding = Encoding.UTF8; //設(shè)置按照何種編碼訪問(wèn),如果不加此行,獲取到的字符串中文將是亂碼 string str = wc.DownloadString(url); return str; } public static string DownloadStreamString(string url) { WebClient wc = new WebClient(); wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36"); Stream objStream = wc.OpenRead(url); StreamReader _read = new StreamReader(objStream, Encoding.UTF8); //新建一個(gè)讀取流,用指定的編碼讀取,此處是utf-8 string str = _read.ReadToEnd(); objStream.Close(); _read.Close(); return str; } public static void DownloadFile(string url, string filename) { WebClient wc = new WebClient(); wc.DownloadFile(url, filename); //下載文件 } public static void DownloadData(string url, string filename) { WebClient wc = new WebClient(); byte [] bytes = wc.DownloadData(url); //下載到字節(jié)數(shù)組 FileStream fs = new FileStream(filename, FileMode.Create); fs.Write(bytes, 0, bytes.Length); fs.Flush(); fs.Close(); } public static void DownloadFileAsync(string url, string filename) { WebClient wc = new WebClient(); wc.DownloadFileCompleted += DownCompletedEventHandler; wc.DownloadFileAsync(new Uri(url), filename); Console.WriteLine("下載中。。。"); } private static void DownCompletedEventHandler(object sender, AsyncCompletedEventArgs e) { Console.WriteLine(sender.ToString()); //觸發(fā)事件的對(duì)象 Console.WriteLine(e.UserState); Console.WriteLine(e.Cancelled); Console.WriteLine("異步下載完成!"); } public static void DownloadFileAsync2(string url, string filename) { WebClient wc = new WebClient(); wc.DownloadFileCompleted += (sender, e) => { Console.WriteLine("下載完成!"); Console.WriteLine(sender.ToString()); Console.WriteLine(e.UserState); Console.WriteLine(e.Cancelled); }; wc.DownloadFileAsync(new Uri(url), filename); Console.WriteLine("下載中。。。"); } }
HttpClient:
HttpClient是.NET4.5引入的一個(gè)HTTP客戶端庫(kù),其命名空間為 System.Net.Http ,.NET 4.5之前我們可能使用WebClient和HttpWebRequest來(lái)達(dá)到相同目的。HttpClient利用了最新的面向任務(wù)模式,使得處理異步請(qǐng)求非常容易。它適合用于多次請(qǐng)求操作,一般設(shè)置好默認(rèn)頭部后,可以進(jìn)行重復(fù)多次的請(qǐng)求,基本上用一個(gè)實(shí)例可以提交任何的HTTP請(qǐng)求。HttpClient有預(yù)熱機(jī)制,第一次進(jìn)行訪問(wèn)時(shí)比較慢,所以不應(yīng)該用到HttpClient就new一個(gè)出來(lái),應(yīng)該使用單例或其他方式獲取HttpClient的實(shí)例
單例模式:
單例模式(Singleton Pattern)這種類型的設(shè)計(jì)模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對(duì)象的最佳方式。
這種模式涉及到一個(gè)單一的類,該類負(fù)責(zé)創(chuàng)建自己的對(duì)象,同時(shí)確保只有單個(gè)對(duì)象被創(chuàng)建。這個(gè)類提供了一種訪問(wèn)其唯一的對(duì)象的方式,可以直接訪問(wèn),不需要實(shí)例化該類的對(duì)象。
單例創(chuàng)建步驟:1、定義靜態(tài)私有對(duì)象;2、定義私有構(gòu)造函數(shù);3、提供公共獲取對(duì)象方法;
單例模式一般分為兩種實(shí)現(xiàn)模式:懶漢模式、餓漢模式(以下為Java代碼實(shí)現(xiàn))
懶漢模式: 默認(rèn)不會(huì)實(shí)例化,什么時(shí)候用什么時(shí)候new
public class Singleton { private static Singleton instance = null; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
這種方式是最基本的實(shí)現(xiàn)方式,這種實(shí)現(xiàn)最大的問(wèn)題就是不支持多線程。因?yàn)闆](méi)有加鎖 synchronized,所以嚴(yán)格意義上它并不算單例模式。
這種方式 lazy loading 很明顯,不要求線程安全,在多線程不能正常工作。
餓漢模式: 類初始化時(shí),會(huì)立即加載該對(duì)象,線程天生安全,調(diào)用效率高
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }
雙檢鎖/雙重校驗(yàn)鎖(DCL,即 double-checked locking):這種方式采用雙鎖機(jī)制,安全且在多線程情況下能保持高性能
public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
HttpClient:
public class HttpClientHelper { private static readonly object LockObj = new object(); private static HttpClient client = null; public HttpClientHelper() { GetInstance(); } public static HttpClient GetInstance() { if (client == null) { lock (LockObj) { if (client == null) { client = new HttpClient(); } } } return client; } public async Task<string> PostAsync(string url, string strJson)//post異步請(qǐng)求方法 { try { HttpContent content = new StringContent(strJson); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); //由HttpClient發(fā)出異步Post請(qǐng)求 HttpResponseMessage res = await client.PostAsync(url, content); if (res.StatusCode == System.Net.HttpStatusCode.OK) { string str = res.Content.ReadAsStringAsync().Result; return str; } else return null; } catch (Exception ex) { return null; } } public string Post(string url, string strJson)//post同步請(qǐng)求方法 { try { HttpContent content = new StringContent(strJson); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); //client.DefaultRequestHeaders.Connection.Add("keep-alive"); //由HttpClient發(fā)出Post請(qǐng)求 Task<HttpResponseMessage> res = client.PostAsync(url, content); if (res.Result.StatusCode == System.Net.HttpStatusCode.OK) { string str = res.Result.Content.ReadAsStringAsync().Result; return str; } else return null; } catch (Exception ex) { return null; } } public string Get(string url) { try { var responseString = client.GetStringAsync(url); return responseString.Result; } catch (Exception ex) { return null; } } }
HttpClient有預(yù)熱機(jī)制,第一次請(qǐng)求比較慢;可以通過(guò)初始化前發(fā)送一次head請(qǐng)求解決:
_httpClient = new HttpClient() { BaseAddress = new Uri(BASE_ADDRESS) }; //幫HttpClient熱身 _httpClient.SendAsync(new HttpRequestMessage { Method = new HttpMethod("HEAD"), RequestUri = new Uri(BASE_ADDRESS + "/") }) .Result.EnsureSuccessStatusCode();
三者區(qū)別列表:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:在C#中使用二叉樹(shù)實(shí)時(shí)計(jì)算海量用戶積分排名的實(shí)現(xiàn)詳解
欄 目:C#教程
本文標(biāo)題:C#中HttpWebRequest、WebClient、HttpClient的使用詳解
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/4566.html
您可能感興趣的文章
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并打開(kāi)的方法
- 01-10C#實(shí)現(xiàn)Winform中打開(kāi)網(wǎng)頁(yè)頁(yè)面的方法
- 01-10C#實(shí)現(xiàn)由四周向中心縮小的窗體退出特效
- 01-10Extjs4如何處理后臺(tái)json數(shù)據(jù)中日期和時(shí)間
- 01-10C#實(shí)現(xiàn)打開(kāi)畫(huà)圖的同時(shí)載入圖片、最大化顯示畫(huà)圖窗體的方法
- 01-10C#中DataGridView常用操作實(shí)例小結(jié)
- 01-10C#編程獲取資源文件中圖片的方法
- 01-10asp.net中XML如何做增刪改查操作
- 01-10C#利用反射技術(shù)實(shí)現(xiàn)去掉按鈕選中時(shí)的邊框效果
- 01-10C#中查找Dictionary中的重復(fù)值的方法


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開(kāi)的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫(xiě)Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 04-02jquery與jsp,用jquery
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置