標籤:style blog http color io os 使用 ar for
12.2 網路編程之HttpClient類
除了可以使用HttpWebRequest類來實現HTTP網路請求之外,我們還可以使用HttpClient類來實現。對於基本的請求操作,HttpClient類提供了一個簡單的介面來處理最常見的任務,並為身分識別驗證提供了適用於大多數方案的合理的預設設定。對於較為複雜的 HTTP 操作,更多的功能包括:執行常見操作(DELETE、GET、PUT 和 POST)的方法;擷取、設定和刪除 Cookie 的功能;支援常見的身分識別驗證設定和模式;非同步方法呼叫上提供的 HTTP 要求進度資訊;訪問有關傳輸的安全通訊端層 (SSL) 詳細資料;在進階應用程式中包含自訂篩選器的功能等。
12.2.1 Get請求擷取字串和資料流資料
(1)擷取字串資料
HttpClient類使用基於任務的非同步模式提供了非常簡化的請求操作,你可以直接調用HttpClient類GetStringAsync方法便可以擷取到網路返回的字串資料。下面我們來看一下使用Get請求來擷取網路返回的字串,實現的代碼很簡潔和簡單,範例程式碼如下所示:
Uri uri = new Uri("http://yourwebsite.com"); HttpClient httpClient = new HttpClient(); // 擷取網路的返回的字串資料 string result = await httpClient.GetStringAsync (uri);
使用GetStringAsync方法是一種簡化的HTTP請求,如果我們要擷取到HTTP請求所返回的整個對象HttpResponseMessage類對象可以使用GetAsync方法。HttpResponseMessage對象是HTTP的相應訊息對象,它包含了網路請求相應的HTTP頭、資料體等資訊。下面我們使用GetAsync方法來擷取網路返回的字串資訊,範例程式碼如下所示:
HttpResponseMessage response = await httpClient.GetAsync(uri); string responseBody = await response.Content.ReadAsStringAsync();
(2)擷取資料流資料
HttpResponseMessage對象的Content屬性工作表示是返回的資料對象,是一個IHttpContent類型的對象。如果要擷取的是資料流資料,可以通過它的ReadAsBufferAsync方法擷取到返回的IBuffer對象,或者通過ReadAsInputStreamAsync地方擷取IInputStream對象,然後再轉化為Stream對象,範例程式碼如下所示:
using (Stream responseStream = (await response.Content.ReadAsInputStreamAsync()).AsStreamForRead()) { int read = 0; byte[] responseBytes = new byte[1000]; do { // 如果read等於0表示Stream的資料以及讀取完畢 read = await responseStream.ReadAsync(responseBytes, 0, responseBytes.Length); } while (read != 0); }
(3)取消網路請求
HttpClient類發起的網路請求都是基於任務的非同步方法呼叫,所以要取消其非同步操作可以通過非同步任務的取消對象CancellationTokenSource對象來取消,這點和HttpWebRequest類是不同。如果使用CancellationTokenSource對象來取消非同步請求會觸發TaskCanceledException異常,這個異常需要我們用try catch語句來捕獲,便可以識別到請求是被取消的。
private CancellationTokenSource cts = new CancellationTokenSource(); try { // 使用CancellationTokenSource對象來控制非同步任務的取消操作 HttpResponseMessage response = await httpClient.GetAsync(new Uri(resourceAddress)).AsTask(cts.Token); responseBody = await response.Content.ReadAsStringAsync().AsTask(cts.Token); cts.Token.ThrowIfCancellationRequested(); } catch (TaskCanceledException) { responseBody = "請求被取消"; } // 調用Cancel方法取消網路請求 if (cts.Token.CanBeCanceled) { cts.Cancel(); }
12.2.2 Post請求發送字串和資料流資料
使用HttpClient類發起Post請求的編程方式也很簡潔,我們可以調用方法PostAsync(Uri uri, IHttpContent content)來直接向目標的地址Post資料,在該方法裡面有兩個參數其中uri就是網路的目標地址,兩外一個content是指你要向目標地址Post的資料對象。在Post資料之前我們首先把我們的資料初始化成為一個IHttpContent對象,那麼實現了IHttpContent介面的類有HttpStringContent類、HttpStreamContent類和HttpBufferContent類,這三個類分表代表了字串類型、資料流類型和二進位類型,那麼資料流類型和二進位類型是可以互相轉換的區別不大。調用PostAsync方法之後會返回一個HttpResponseMessage對象,通過這個HTTP的相應訊息對象我們就可以擷取Post請求之後的返回的結果資訊。Post請求發送字串和資料流資料的程式碼範例如下所示:
(1)Post請求發送字串資料
HttpStringContent httpStringContent = new HttpStringContent("hello Windows Phone"); HttpResponseMessage response = await httpClient.PostAsync(uri, httpStringContent).AsTask(cts.Token); string responseBody = await response.Content.ReadAsStringAsync().AsTask(cts.Token);
(2)Post請求發送資料流資料
HttpStreamContent streamContent = new HttpStreamContent(stream.AsInputStream()); HttpResponseMessage response = await httpClient.PostAsync(uri, streamContent).AsTask(cts.Token); string responseBody = await response.Content.ReadAsStringAsync().AsTask(cts.Token);
除了使用PostAsync方法之外,我們還可以使用SendRequestAsync方法來發送網路請求,SendRequestAsync方法既可以使用Get方式也可以使用Post方式。SendRequestAsync方法發送的訊息類型是HttpRequestMessage類對象,HttpRequestMessage類表示HTTP的請求訊息類,你可以通過HttpRequestMessage對象佈建要求的類型(Get/Post)和傳輸的資料對象。使用SendRequestAsync方法的程式碼範例如下所示:
// 建立HttpRequestMessage對象 HttpStreamContent streamContent = new HttpStreamContent(stream.AsInputStream()); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri(resourceAddress)); request.Content = streamContent; // 發送資料 HttpResponseMessage response = await httpClient.SendRequestAsync(request).AsTask(cts.Token); string responseBody = await response.Content.ReadAsStringAsync().AsTask(cts.Token);
12.2.3 設定和擷取Cookie
Cookie是指某些網站為了辨別使用者身份、進行回話跟蹤而儲存在使用者本地終端上的資料(通常經過加密)。那麼當我們在使用HTTP請求的時候,如果伺服器返回的資料待用Cookie資料,我們也是可以擷取出來,儲存在本地,下次發起HTTP請求的時候就會帶上這些Cookie的資料。
在HttpClient類的網路請求中我們可以通過HttpBaseProtocolFilter類來擷取網站的Cookie資訊,HttpBaseProtocolFilter類表示是HttpClient的HTTP請求的基礎協議的過濾器。擷取Cookie的程式碼範例如下所示:
// 建立一個HttpBaseProtocolFilter對象 HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter(); // 通過HttpBaseProtocolFilter對象擷取使用HttpClient進行過網路請求的地址的Cookie資訊 HttpCookieCollection cookieCollection = filter.CookieManager.GetCookies(new Uri(resourceAddress)); // 遍曆整個Cookie集合的Cookie資訊 foreach (HttpCookie cookie in cookieCollection) { }
當然我們在發送HTTP請求的時候也一樣可以帶上Cookie資訊,如果伺服器可以識別到Cookie資訊那麼就會通過Cookie資訊來進行一些操作,比如Cookie資訊資訊帶有使用者名稱和密碼的加密資訊,那麼就可以免去登陸的步驟。在HttpClient的網路請求裡面HttpCookie類表示是一個Cookie對象,建立好Cookie對象之後通過HttpBaseProtocolFilter對象的CookieManager屬性來設定Cookie,然後發送網路請求,這時候的網路請求就會把Cookie資訊給帶上。設定Cookie的程式碼範例如下所示:
// 建立一個HttpCookie對象,"id"表示是Cookie的名稱,"localhost"是主機名稱,"/"是表示伺服器的虛擬路徑 HttpCookie cookie = new HttpCookie("id", "yourwebsite.com", "/"); // 設定Cookie的值 cookie.Value = "123456"; // 設定Cookie存活的時間,如果設定為null表示只是在一個會話裡面生效 cookie.Expires = new DateTimeOffset(DateTime.Now, new TimeSpan(0, 1, 8)); // 在過濾器裡面設定Cookie HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter(); bool replaced = filter.CookieManager.SetCookie(cookie, false);
……接下來可以向"yourwebsite.com"遠程主機發起請求
12.2.4 網路請求的進度監控
HttpClient的網路請求是支援進度監控,通過非同步任務的IProgress<T>對象可以直接監控到HttpClient的網路請求返回的進度資訊,返回的進度對象是HttpProgress類對象。在進度對象HttpProgress裡麵包含了下面的一些資訊:Stage(當前的狀態)、BytesSent(已發送的資料大小)、BytesReceived(已接收的資料大小)、Retries(重試的次數)、TotalBytesToSend(總共需要發送的資料大小)和TotalBytesToReceive(總共需要接收的資料大小)。網路請求進度監控的程式碼範例如下所示:
// 建立IProgress<HttpProgress>對象 IProgress<HttpProgress> progress = new Progress<HttpProgress>(ProgressHandler); // 在非同步任務中加入進度監控 HttpResponseMessage response = await httpClient.PostAsync(new Uri(resourceAddress), streamContent).AsTask(cts.Token, progress); // 進度監控的回調方法 private void ProgressHandler(HttpProgress progress) { // 在這裡可以通過progress參數擷取到進度的相關資訊 }
本文來源於《深入淺出Windows Phone 8.1 應用開發》
WP8.1 Runtime文章列表:http://www.cnblogs.com/linzheng/p/3998037.html
原始碼下載:http://vdisk.weibo.com/s/zt_pyrfNHb99O
歡迎關注我的微博@WP林政 公眾號:wp開發(號:wpkaifa)
WP8.1技術交流群:372552293
[深入淺出WP8.1(Runtime)]網路編程之HttpClient類