C# System.Net.Http.HttpClient使用說明


一、 System.Net.Http.HttpClient簡介

System.Net.Http 是微軟推出的最新的 HTTP 應用程序的編程接口, 微軟稱之為“現代化的 HTTP 編程接口”, 主要提供如下內容:

1. 用戶通過 HTTP 使用現代化的 Web Service 的客戶端組件

2. 能夠同時在客戶端與服務端同時使用的 HTTP 組件(比如處理 HTTP 標頭和消息), 為客戶端和服務端提供一致的編程模型。

 

命名空間 System.Net.Http 以及 System.Net.Http.Headers 提供了如下內容:

1. HttpClient 發送和接收 HTTP 請求與響應;

2. HttPRequestMessage and HttpResponseMessage 封裝了 RFC 2616 定義的 HTTP 消息;

3. HttpHeaders 封裝了 RFC 2616 定義的 HTTP 標頭;

4. HttpClientHandler 負責生成HTTP響應消息的HTTP處理程序。

System.Net.Http 能夠處理多種類型的 RFC 2616 定義的 HTTP 實體正文, 如下圖所示:

 

 

  此外, System.Net.Http 對 HTTP 消息的處理采用了職責鏈模式, 這里有一遍不錯的介紹, 這里就不再多說了。

 

  System.Net.Http 最早是和 asp.net Mvc4 同時出現, 是一個第三方組件,名稱是Microsoft HTTP Client Libraries,可以在 .Net 4.0 中使用。 隨着 .Net 4.5 的發布, System.Net.Http 正式成為 .Net 基礎類庫, 目前已經可以在 .Net 4.0/4.5 、 Windows Phone 、 以及 Windows Store App 中使用。 

  HttpClient 組件類實例為一個會話發送 HTTP 請求。 HttpClient 實例設置為集合會應用於該實例執行的所有請求。 此外,每 HttpClient 實例使用自己的連接池,隔離其他 HttpClient實例的執行請求。 HttpClient 也是更具體的 HTTP 客戶端的基類。 

  默認情況下,使用 HttpWebRequest 向服務器發送請求。 這一行為可通過在接受一個HttpMessageHandler實例作為參數的構造函數重載中指定不同的通道來更改。

  如果需要身份驗證或緩存的功能,WebRequestHandler 可使用配置項和實例傳遞給構造函數。 返回的處理程序傳遞到采用 HttpMessageHandler 參數的某構造進行返回參數傳遞。 

  如果使用 HttpClient 和相關組件類的 app 在 System.Net.Http 命名空間用於下載大量數據 (可達 50 MB 或更多),則應用程序應這些下載的流和不使用默認值緩沖區。 如果使用默認值緩沖區客戶端內存使用量會非常大,可能會導致顯着降低的性能。 

  

  對於 HttpClient的基本使用方法,示例代碼如下:

//聲明HttpClient

HttpClient client = new HttpClient

{

BaseAddress = new Uri("http://www.163.com")

};

//多線程中跨線程進行信息顯示委托

public delegate void ShowMsgDelegate(string text);

public void ShowMsgText(string text)

{

txtMsg.Text=text;

}

//信息顯示

private void ShowMessage(string msg)

{

if (this.InvokeRequired)

{

this.Invoke(new ShowMsgDelegate(ShowMsgText), msg);

}

else

{

ShowMsgText(msg);

}

}

 

// Get form data to server

 

private void btnGet_Click(object sender, EventArgs e)

{

// Get string from server

client.GetStringAsync("browserhttp/").ContinueWith(t =>

{

if (t.IsFaulted)

{

ShowMessage("返回信息錯誤:" + t.Result);

}

else

{

ShowMessage("成功:" + t.Result);

}

});

}

 

 

 

// Post form data to server

 

private void btnPost_Click(object sender, EventArgs e)

{

var param = new Dictionary<string, string> {

{"Name", "TOM Post"},

{"Age", "11"},

{"Birthday", DateTime.Now.ToString("yyyyMMdd")}

};

 

client.PostAsync("browserhttp/", new FormUrlEncodedContent(param)).ContinueWith(t =>

{

ShowMsgDelegate showmsg = new ShowMsgDelegate(ShowMsgText);

if (t.IsFaulted)

{

ShowMessage("返回信息錯誤:" + t.Result);

 

}

else

{

HttpResponseMessage response = t.Result;

ShowMessage(response.StatusCode.ToString());

}

});

 

}

// PUT to update

private void btnPut_Click(object sender, EventArgs e)

{

var param = new Dictionary<string, string> {

{"Id", "10" },

{"Name", "Tom Post"},

{"Age", "10"},

{"Birthday", DateTime.Now.ToString("yyyyMMdd")}

};

client.PutAsync("clienthttp/1", new FormUrlEncodedContent(param)).ContinueWith(t =>

{

if (t.IsFaulted)

{

ShowMessage("返回信息錯誤:" + t.Result);

}

else

{

HttpResponseMessage response = t.Result;

ShowMessage(response.StatusCode.ToString());

}

});

}

 

// DELETE

 

private void btnDel_Click(object sender, EventArgs e)

{

client.DeleteAsync("clienthttp/1").ContinueWith(t =>

{

if (t.IsFaulted)

{

ShowMessage("返回信息錯誤:" + t.Result);

 

}

else

{

HttpResponseMessage response = t.Result;

ShowMessage(response.StatusCode.ToString());

}

});

}

支持職責鏈模式的 MessageProcessingHandler ,MessageProcessingHandler - 一種基本的 HTTP 消息處理程序。這是最容易進行派生的處理程序,應該作為大多數自定義處理程序的起點。 自已定義了一個新的MessageProcessingHandler處理程序,如下面的示例代碼所示:

public class CustomProcessingHandler : MessageProcessingHandler {

 

protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, CancellationToken cancellationToken) {

if (request.Method != HttpMethod.Get && request.Method != HttpMethod.Post) {

request.Headers.TryAddWithoutValidation("RequestMethod", request.Method.Method);

request.Method = HttpMethod.Post;

}

return request;

}

 

protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, CancellationToken cancellationToken) {

var request = response.RequestMessage;

if (request.Headers.Contains("RequestMethod")) {

IEnumerable<string> values;

if (request.Headers.TryGetValues("RequestMethod", out values)) {

request.Method = new HttpMethod(values.First());

}

}

return response;

}

}

  使用起來也是非常簡單的:

private void btnCustom_Click(object sender, EventArgs e)

{

var customHandler = new CustomProcessingHandler

{

InnerHandler = new HttpClientHandler()

};

 

var client = new HttpClient(customHandler, true)

{

BaseAddress = new Uri("http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl")

};

var task = client.GetAsync(client.BaseAddress);

task.Result.EnsureSuccessStatusCode();

HttpResponseMessage response = task.Result;

txtStatusCode.Text = response.StatusCode + " " + response.ReasonPhrase + Environment.NewLine;

txtStatusText.Text = "請求返回結果如下 ...";

var result = response.Content.ReadAsStringAsync();

txtMsg.Text = result.Result; ;

 

}

二、使用 HttpClient 進行連接

使用 HttpClient 進行連接

  使用 System.Net.Http 命名空間中的 HttpClient 類可以向 WebService發送 POST與GET 請求並檢索響應數據。

 

  System.Net.Http 命名空間中的類可為現代 HTTP 應用提供編程接口。System.Net.Http 命名空間和相關的 System.Net.Http.Headers 命名空間提供的 HTTP 客戶端組件,允許用戶通過 HTTP 使用現代的 WebService。

 

  HttpClient 類用於通過 HTTP 發送和接收基本要求。它提供了一個用於從 URI 所標識的資源發送 HTTP 請求和接收 HTTP 響應的基類。該類可用來向 Web Service發送 GET、PUT、POST、DELETE 以及其他請求。上述每種請求都作為異步操作進行發送。

 

  HttpResponseMessage 類用於聲明從 HTTP 請求接收到的 HTTP 響應消息。HTTP 消息由 IETF 在 RFC 2616 中進行定義。 

 

  HttpContent 類是用於聲明 HTTP 實體正文和內容標題的基類。 在這種情況下,HttpContent 用於聲明 HTTP 響應。

 

 

 

  以下示例使用 .NET Framework 4.0 的 C#。同時你必須對 RFC 2616 中詳細描述的 HTTP 請求有基本的了解。

 

一、 創建新項目

 

  1. 打開 Microsoft Visual Studio 2010,然后從“文件”菜單中選擇“新建項目”。在模板列表中,選擇 Visual C#。在該區域下面,選擇“Windows 應用程序應用”,然后選擇“空白應用程序”。將該應用程序命名為 winHttpClientBase,然后單擊“確定”。

 

  2. 添加Microsoft HTTP Client Libraries的引用如下圖1,圖2,圖3,圖4。

 

 

 

圖1

 

 

 

 

 

圖2

 

 

 

圖3

 

 

 

 

 

圖4

 

二、設置啟用網絡訪問的功能

 

  需要為應用設置網絡功能,以啟用家庭網絡或工作網絡以及 Internet 的訪問。你需要為你的應用啟用網絡功能,因為客戶端需要連接到因特網上的 Web Service。

 

  對於使用 HttpClient 連接到另一台計算機上 Web Service的應用,該應用將需要設置網絡功能。

 

三、添加 Windows 控件 

 

  在本小節中,我們將在添加顯示數據的控件和內容,每個控件的大小和位置,我們的用戶界面如下。

 

 

  本示例使用了簡單的 Windows 控件,包括:

 

  o 包含Label 標簽、輸入 URI 地址的 TextBox和用於啟動異步請求的Button(請求) 。

 

  o 包一個顯示狀態與狀態代碼的兩個Lable與TextBox。

 

  o 包一個顯示請求結果的TextBox。用於顯示從 Web 服務接收到的信息。在此示例中,HTTP GET 操作的結果會以包含 HTML 標記的純文本顯示。

 

 

 

 

 

  四、創建 HttpClient,發送 GET 請求並檢索響應

 

  以下代碼將首先創建 HttpClient 對象。

 

  1. 首先創建 HttpClient 對象。我們還在 HttpClient 對象上設置兩個屬性。

 

  HttpClient.MaxResponseContentBufferSize 屬性的默認值是整數的最大值。為了限制應用作為來自 Web 服務的響應接受的數據量,我們將此屬性設置為一個較小的值。

 

  默認情況下,HttpClient 對象不會將用戶代理標識頭隨 HTTP 請求一起發送到 Web 服務。某些 HTTP 服務器(包括某些 Microsoft Web 服務器)要求從客戶端發送的 HTTP 請求附帶用戶代理標識頭,並且如果沒有標識頭,則返回錯誤。為了避免這些錯誤,使用 HttpClient.DefaultRequestHeaders 屬性添加了用戶代理標頭。

 

  2. 打開 Form1.cs 文件。然后將如下代碼添加到該文件中。

 

   

 

復制代碼
復制代碼
   private void btnRequest_Click(object sender, EventArgs e)

        {

            Init();

        }

        private HttpClient httpClient;

 

    public void Init()

    {

        this.InitializeComponent();

        httpClient = new HttpClient();

        // Limit the max buffer size for the response so we don't get overwhelmed

        httpClient.MaxResponseContentBufferSize = 256000;

        httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");

    }

 

 

 
復制代碼
復制代碼

 

 

 

 

 

  3. 發送 GET 請求並檢索響應。

 

  在單擊“請求”按鈕之后, txtStatusText和 txtMsg文本框中的文本將被更新,然后應用程序使用txtUrl文本框中的 URI 地址發送 HTTP GET 請求並等待響應。如果發生錯誤或異常,結果會顯示在 txtStatusText文本框中。如果沒有錯誤發生,則來自該 Web 服務的響應將顯示在 txtMsg文本框中。

 

  如果是使用vs 2012與net 4.5 則可以在 C# 和 Visual Basic 中使用 await 關鍵字時,發送 GET 請求並異步檢索響應的代碼與我們用於同步完成該操作的代碼相似。只有在該方法被定義為 async 時,才能使用 await 關鍵字。

 

  如果 Web 服務器返回 HTTP 錯誤狀態代碼,則 HttpResponseMessage.EnsureSuccessStatusCode 方法將引發異常。 如果發生錯誤,則對任何異常使用 try/catch 塊,並在 txtStatusText 文本框中顯示異常信息。在 try 塊中,顯示 Web 服務所返回的狀態(txtStatusText)和狀態代碼(txtStatusCode)。

 

  HttpResponseMessage.Content 屬性聲明 HTTP 響應的內容。HttpContent.ReadAsStringAsync 方法將 HTTP 內容作為異步操作寫入到字符串中。 為了方便顯示,我們將所返回的 HTML 文本中的所有 <br> 標記都替換成了新行。

 

 

 

 

 

復制代碼
復制代碼
 

         private  void GetHtml()

        {

            try

            {

                string responseBodyAsText;

                txtMsg.Text = "";

                txtStatusText.Text = "Waiting for response ...";

                var task = httpClient.GetAsync(new Uri(txtUrl.Text));

                task.Result.EnsureSuccessStatusCode();

                //var result = task.Result.Content.ReadAsStringAsync();

                HttpResponseMessage response = task.Result;

                 

                

                

                txtStatusText.Text = response.StatusCode + " " + response.ReasonPhrase + Environment.NewLine;

                var result =  response.Content.ReadAsStringAsync();

                responseBodyAsText = result.Result;

                responseBodyAsText = responseBodyAsText.Replace("<br>", Environment.NewLine); // Insert new lines

                txtMsg.Text = responseBodyAsText;

            }

            catch (HttpRequestException hre)

            {

                txtStatusText.Text = hre.ToString();

            }

            catch (Exception ex)

            {

                // For debugging

                txtStatusText.Text = ex.ToString();

            }

        }

 

 
復制代碼
復制代碼

 

 

 

  如果使用 System.Net.Http 命名空間中的 HttpClient 和相關類的應用用於下載大量數據(50M 或更多),則該應用應流式傳輸這些下載內容並且不使用默認緩沖。如果使用了默認緩沖,則客戶端內存使用量將變得非常大,這可能會導致大幅度降低性能。

 

  當 HttpClient 類和相關類的成員檢測到無效的統一資源標識符 (URI) 時,則將引發 UriFormatException 此例外不可以在 Windows 應用商店應用中使用。若要在這種情況下捕獲此例外,請為 FormatException 編寫捕獲語句。 

 

 

 

 

 

五、小結

 

  在本文中,我們已了解如何使用 HttpClient 類向 Web 服務發送 GET 請求以及如何使用 HttpResponseMessage 和 HttpContent 類檢索響應。

 

  HttpClientBasic 完整示例

 

 

 

復制代碼
復制代碼
public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void btnRequest_Click(object sender, EventArgs e)

        {

            Init();

            GetHtml();

        }

 

        private void GetHtml()

        {

            try

            {

                string responseBodyAsText;

                txtMsg.Text = "";

                txtStatusText.Text = "等待請求返回 ...";

                var task = httpClient.GetAsync(new Uri(txtUrl.Text));

                task.Result.EnsureSuccessStatusCode();

                HttpResponseMessage response = task.Result;

                txtStatusCode.Text = response.StatusCode + " " + response.ReasonPhrase + Environment.NewLine;

                txtStatusText.Text = "請求返回結果如下 ...";

                var result = response.Content.ReadAsStringAsync();

                responseBodyAsText = result.Result;

                responseBodyAsText = responseBodyAsText.Replace("<br>", Environment.NewLine); // Insert new lines

 

                txtMsg.Text = responseBodyAsText;

            }

            catch (HttpRequestException hre)

            {

                txtStatusText.Text = hre.ToString();

            }

            catch (Exception ex)

            {

                // For debugging

                txtStatusText.Text = ex.ToString();

            }

        }

 

 

        private HttpClient httpClient;

 

        public void Init()

        {

 

            httpClient = new HttpClient();            

            httpClient.MaxResponseContentBufferSize = 256000;

            httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");

        }

    }

 
復制代碼
復制代碼

 

 

 

可以將 HttpClientHandler 類與 HttpClient 類結合使用,以設置有關 HTTP 請求的選項。 

 

 

 

 

 

 

三、使用 HttpClient 檢索與獲取過程數據

 

如何使用 HttpClient 處理程序

 

  將 HttpClientHandler 類與 System.Net.Http 命名空間中的 HttpClient 類結合使用,以向 Web Service發送 GET 請求並檢索響應。

 

  HttpClient 類用於通過 HTTP 發送和接收基本要求。它提供了一個用於從 URI 所標識的資源發送 HTTP 請求和接收 HTTP 響應的基類。該類可用來向 Web 服務發送 GET、PUT、POST、DELETE 以及其他請求。上述每種請求都作為異步操作進行發送。

 

  HttpClientHandler 類是 HttpClient 的默認消息處理程序。HttpClientHandler 類以及從該類派生的類讓開發人員可以對 HTTP 請求配置從代理到身份驗證的一系列選項。

 

一: 創建新項目

 

  打開 Microsoft Visual Studio 2010,然后從“文件”菜單中選擇“新建項目”。在模板列表中,選擇 Visual C#。在該區域下面,選擇“Windows”,然后選擇“Windows窗體應用程序”。將該應用程序命名為 HttpClientHandlerSample,然后單擊“確定”。

 

二: 添加 WINDOWS UI 

 

   在本節中,我們將在 Windows Form 中定義應用的布局,以指定應用中每個對象的大小和位置。 通過添加顯示數據的控件和內容,我們已經完成了應用的用戶界面。如下圖。

 

 

 

 

 

三: 創建 HttpClientHandler,發送 GET 請求並檢索響應

 

  以下示例代碼將首先創建 HttpClientHandler 對象。該代碼還將對該對象設置一個屬性,並使用 HttpClientHandler 創建一個 HttpClient 對象。

 

  1. 首先創建 HttpClientHandler 對象。將 AllowAutoRedirect 屬性設置為 false。此示例顯示了如何使用 HttpClientHandler 屬性來設置有關 HTTP 請求的選項。

 

  AllowAutoRedirect 屬性指示 HttpClientHandler 對象的請求是否應遵循重定向響應。此屬性的默認值是 true。如果此屬性被設置為 false,則不會遵循 Web 服務的重定向請求。

 

  然后,使用 HttpClientHandler 對象創建 HttpClient 對象。我們還在 HttpClient 對象上設置兩個屬性。HttpClient.MaxResponseContentBufferSize 屬性的默認大小是整數的最大大小。為了限制應用作為來自 Web 服務的響應接受的數據量,我們將此屬性設置為一個較小的值。

 

  默認情況下,HttpClient 對象不會將用戶代理標頭隨 HTTP 請求一起發送到 Web 服務。某些 HTTP 服務器(包括某些 Microsoft Web 服務器)要求從客戶端發送的 HTTP 請求附帶用戶代理標頭,並且如果沒有標頭,則返回錯誤。為了避免這些錯誤,示例使用 HttpClient.DefaultRequestHeaders 屬性添加了用戶代理標頭。

 

  打開 Form1.cs 文件,然后將如下代碼添加到該文件中。

 

 

 

復制代碼
復制代碼
   private HttpClient httpClient;

    private HttpClientHandler handler;

 

    public void Init()

    {

        txtUrl.Text = "http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl";

        handler = new HttpClientHandler();

        handler.AllowAutoRedirect=false; 

 

        httpClient = new HttpClient(handler);

 

        // Limit the max buffer size for the response so we don't get overwhelmed

        httpClient.MaxResponseContentBufferSize = 256000;

        // Add a user-agent header

        httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");

    }
復制代碼
復制代碼

 

 

 

   2. 發送 GET 請求並檢索響應。

 

  在單擊“請求”按鈕之后,txtStatusText 和 txtMsg兩個文本框中的文本將被更新,然后使用輸入到txtUrl文本框中的 URI 地址發送 HTTP GET 請求並等待響應。如果發生錯誤或異常,錯誤信息會顯示在 txtStatusText文本框中。如果沒有錯誤發生,則來自該 Web 服務的響應將顯示在 txtMsg文本框中。

 

  說明:

 

  在  visual studio 2012 中的 C# 和 Visual Basic 中可以使用 await 關鍵字時,發送 GET 請求並異步檢索響應的代碼與我們用於同步完成該操作的代碼相似。只有在該方法被定義為 async 時,才能使用 await 關鍵字。

 

  如果 Web 服務器返回 HTTP 錯誤狀態代碼,則 HttpResponseMessage.EnsureSuccessStatusCode 方法將引發異常。 如果發生錯誤,則對任何異常使用 try/catch 塊,並把錯誤信息顯示在txtStatusText 文本框中的異常消息。在 try 塊中,顯示 Web 服務所返回的狀態和響應。

 

  HttpResponseMessage.Content 屬性聲明 HTTP 響應的內容。HttpContent.ReadAsStringAsync 方法將 HTTP 內容作為異步操作寫入到字符串中。 

 

 

 

  

 

復制代碼
復制代碼
    private void btnRequest_Click(object sender, EventArgs e)

    {

           try

            {

                

                txtMsg.Text=string.Empty;

                txtStatusText.Text = "等待請求返回 ...";

                var task = httpClient.GetAsync(txtUrl.Text);

                task.Result.EnsureSuccessStatusCode();

                HttpResponseMessage response = task.Result;

                

             

                txtStatusCode.Text = response.StatusCode + " " + response.ReasonPhrase + Environment.NewLine;

                txtStatusText.Text = "請求返回結果如下 ...";

                var result = response.Content.ReadAsStringAsync();

               string responseBodyAsText = result.Result;

                responseBodyAsText = responseBodyAsText.Replace("<br>", Environment.NewLine); // Insert new lines

 

                txtMsg.Text=responseBodyAsText;

            }

            catch (HttpRequestException hre)

            {

                txtStatusText.Text = hre.ToString();

            }

            catch (Exception ex)

            {


                txtStatusText.Text = ex.ToString();

            }

 

    }

 
復制代碼
復制代碼

 

 

 

 

 

 

 

 

 

備注

 

在本文中,我們介紹了如何將 HttpClientHandler 與 HttpClient 類結合使用,以向 Web 服務發送 GET 請求,以及如何使用 HttpResponseMessage 和 HttpContent 類檢索響應。HttpClientHandler 允許應用設置有關 HTTP 請求的選項。

 

有一些 HTTP 消息處理程序可以與 HttpClient 類結合使用。

 

  • HttpClientHandler - 本文中 HttpClient 所用的默認消息處理程序。
  • MessageProcessingHandler - 一種基本的 HTTP 消息處理程序。這是最容易進行派生的處理程序,應該作為大多數自定義處理程序的起點。
  • DelegatingHandler - 一種基本的 HTTP 處理程序,可將 HTTP 響應消息的處理委派給其他處理程序。

 

 

 

完整示例:

 

 

 

 

 

復制代碼
復制代碼
HttpClientHandler 示例
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Http;

namespace HttpClientHandlerSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Init();
        }

          private HttpClient httpClient;
    private HttpClientHandler handler;

    public void Init()
    {
        txtUrl.Text = "http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl";
        handler = new HttpClientHandler();
        handler.AllowAutoRedirect=false; 

        httpClient = new HttpClient(handler);

        // Limit the max buffer size for the response so we don't get overwhelmed
        httpClient.MaxResponseContentBufferSize = 256000;
        // Add a user-agent header
        httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
    }

    private void btnRequest_Click(object sender, EventArgs e)
    {
           try
            {
                
                txtMsg.Text=string.Empty;
                txtStatusText.Text = "等待請求返回 ...";
                var task = httpClient.GetAsync(txtUrl.Text);
                task.Result.EnsureSuccessStatusCode();
                HttpResponseMessage response = task.Result;
                
             
                txtStatusCode.Text = response.StatusCode + " " + response.ReasonPhrase + Environment.NewLine;
                txtStatusText.Text = "請求返回結果如下 ...";
                var result = response.Content.ReadAsStringAsync();
               string responseBodyAsText = result.Result;
                responseBodyAsText = responseBodyAsText.Replace("<br>", Environment.NewLine); // Insert new lines

                txtMsg.Text=responseBodyAsText;
            }
            catch (HttpRequestException hre)
            {
                txtStatusText.Text = hre.ToString();
            }
            catch (Exception ex)
            {
                txtStatusText.Text = ex.ToString();
            }
    }
    }
}
復制代碼
復制代碼

 

 

四、實例(模擬post登錄博客園)

 

首先,需要說明的是,本實例環境是win7 64位+vs 2013+ .net 4.5框架。

 

1.使用vs2013新建一個控制台程序,或者窗體程序,如下圖所示:

 

 

 

 

2.必須引入System.Net.Http框架,否則將不能使用httpclient

 

 

 

 

 

 

 

3.實現代碼

 

復制代碼
復制代碼
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public class Class1
    {
        private static String dir = @"C:\work\";

        /// <summary>
        /// 寫文件到本地
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="html"></param>
        public static void Write(string fileName, string html)
        {
            try
            {
                FileStream fs = new FileStream(dir + fileName, FileMode.Create);
                StreamWriter sw = new StreamWriter(fs, Encoding.Default);
                sw.Write(html);
                sw.Close();
                fs.Close();

            }catch(Exception ex){
                Console.WriteLine(ex.StackTrace);
            }
           
        }

        /// <summary>
        /// 寫文件到本地
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="html"></param>
        public static void Write(string fileName, byte[] html)
        {
            try
            {
                File.WriteAllBytes(dir + fileName, html);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }
            
        }

        /// <summary>
        /// 登錄博客園
        /// </summary>
        public static void LoginCnblogs()
        {
            HttpClient httpClient = new HttpClient();
            httpClient.MaxResponseContentBufferSize = 256000;
            httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36");
            String url = "http://passport.cnblogs.com/login.aspx";
            HttpResponseMessage response = httpClient.GetAsync(new Uri(url)).Result;
            String result = response.Content.ReadAsStringAsync().Result;

            String username = "hi_amos";
            String password = "密碼";

            do
            {
                String __EVENTVALIDATION = new Regex("id=\"__EVENTVALIDATION\" value=\"(.*?)\"").Match(result).Groups[1].Value;
                String __VIEWSTATE = new Regex("id=\"__VIEWSTATE\" value=\"(.*?)\"").Match(result).Groups[1].Value;
                String LBD_VCID_c_login_logincaptcha = new Regex("id=\"LBD_VCID_c_login_logincaptcha\" value=\"(.*?)\"").Match(result).Groups[1].Value;

                //圖片驗證碼
                url = "http://passport.cnblogs.com" + new Regex("id=\"c_login_logincaptcha_CaptchaImage\" src=\"(.*?)\"").Match(result).Groups[1].Value;
                response = httpClient.GetAsync(new Uri(url)).Result;
                Write("amosli.png", response.Content.ReadAsByteArrayAsync().Result);
                
                Console.WriteLine("輸入圖片驗證碼:");
                String imgCode = "wupve";//驗證碼寫到本地了,需要手動填寫
                imgCode =  Console.ReadLine();

                //開始登錄
                url = "http://passport.cnblogs.com/login.aspx";
                List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
                paramList.Add(new KeyValuePair<string, string>("__EVENTTARGET", ""));
                paramList.Add(new KeyValuePair<string, string>("__EVENTARGUMENT", ""));
                paramList.Add(new KeyValuePair<string, string>("__VIEWSTATE", __VIEWSTATE));
                paramList.Add(new KeyValuePair<string, string>("__EVENTVALIDATION", __EVENTVALIDATION));
                paramList.Add(new KeyValuePair<string, string>("tbUserName", username));
                paramList.Add(new KeyValuePair<string, string>("tbPassword", password));
                paramList.Add(new KeyValuePair<string, string>("LBD_VCID_c_login_logincaptcha", LBD_VCID_c_login_logincaptcha));
                paramList.Add(new KeyValuePair<string, string>("LBD_BackWorkaround_c_login_logincaptcha", "1"));
                paramList.Add(new KeyValuePair<string, string>("CaptchaCodeTextBox", imgCode));
                paramList.Add(new KeyValuePair<string, string>("btnLogin", "登  錄"));
                paramList.Add(new KeyValuePair<string, string>("txtReturnUrl", "http://home.cnblogs.com/"));
                response = httpClient.PostAsync(new Uri(url), new FormUrlEncodedContent(paramList)).Result;
                result = response.Content.ReadAsStringAsync().Result;
                Write("myCnblogs.html",result);
            } while (result.Contains("驗證碼錯誤,麻煩您重新輸入"));

            Console.WriteLine("登錄成功!");
            
            //用完要記得釋放
            httpClient.Dispose();
        }

        public static void Main()
        {
              LoginCnblogs();
        }

}
復制代碼
復制代碼

 

 

 

 

 

代碼分析:

 

首先,從Main函數開始,調用LoginCnblogs方法;

 

其次,使用GET方法:

 

 HttpResponseMessage response = httpClient.GetAsync(new Uri(url)).Result;
 String result = response.Content.ReadAsStringAsync().Result;

 

再者,使用POST方法:

 

  List<KeyValuePair<String, String>> paramList = new List<KeyValuePair<String, String>>();
                paramList.Add(new KeyValuePair<string, string>("__EVENTTARGET", ""));
  ....
                response = httpClient.PostAsync(new Uri(url), new FormUrlEncodedContent(paramList)).Result;
                result = response.Content.ReadAsStringAsync().Result;

 

最后,注意其返回值可以是string,也可以是byte[],和stream的方式,這里看你需要什么吧。

 

 

 

 

4.登錄成功后的截圖

 

1).使用瀏覽器登錄后的截圖:

 

 

2).使用Httpcliet登錄后的截圖:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM