.NET4.5 使用HttpClient來異步發送POST請求並解析GZIP回應


在新的C# 5.0和.NET 4.5環境下,微軟為C#加入了async/await,同時還加入新的System.Net.Http.dll類庫。這一切都大大簡化了(甚至可以說是革命性得改變了)傳統.NET HTTP操作處理的方式。

相比最新的模型,之前.NET 4.0和C# 4.0的時代的HTTP處理方式就顯得弱爆了。

首先,如果寫成一異步的話。會創造一大堆難看的APM異步執行方法。如果用Lambda的話,就得嵌套多層,也會看着不爽。

其次,關於HTTP特有的,就是用戶必須手動把URL參數編碼並且正確連接然后放入到HTTP請求中。而.NET 4.5中的HttpContent類型的多個派生類型可以支持更快捷的HTTP數據內容創建,我們可以使用FormUrlEncodedContent來完成上述需求。

還有就是自動解壓縮HTTP回應中的GZIP的問題:.NET 4.0中在HttpWebRequest的AutomaticDecompression屬性中,在.NET 4.5中的HttpClient類型中,可以使用HttpClientHandler的AutomaticDecompression屬性,前后兩者對應值都是DecompressionMethods枚舉類型,這個類型在.NET 2.0就有了。因此命名空間在System.Net中。

 

我們可以拿一個街旁網API來做演示,整個過程如下如下:

1. 創建一個HTTP POST請求。

2. 服務器會返回GZip壓縮后的數據。

3. 讀取並輸出結果。

 

代碼如下:

//C# 5.0+ / .NET 4.5+

//+ using System.Net;

//+ using System.Net.Http(需引用System.Net.Http.dll類庫);

 

static void Main(string[] args)

{

    doo();

    System.Threading.Thread.Sleep(-1);

}

 

static async void doo()

{

    //設置必要參數

    //示例API可以參考:http://dev.jiepang.com/doc/get/users/show

    var url = "http://api.jiepang.com/v1/users/show";

    var userId = "633899402";

 

    //設置HttpClientHandler的AutomaticDecompression

    var handler = new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip };

 

    //創建HttpClient(注意傳入HttpClientHandler)

    using (var http = new HttpClient(handler))

    {

        //使用FormUrlEncodedContent做HttpContent

        var content = new FormUrlEncodedContent(new Dictionary<stringstring>()

        {

            {"id", userId},

            {"force_gzip""1"}

        });

 

        //await異步等待回應

        var response = await http.PostAsync(url, content);

 

        //await異步讀取最后的JSON(注意此時gzip已經被自動解壓縮了,因為上面的AutomaticDecompression = DecompressionMethods.GZip)

        Console.WriteLine(await response.Content.ReadAsStringAsync());

    }

}

運行后,如果成功的話會輸出包含用戶信息的JSON!

注意:

貌似街旁網已經把這個API改成了了強制OAuth驗證(雖然文檔上還寫着“不需要驗證”)。所以運行結果不會輸出賬戶信息,而會輸出有包含錯誤信息的JSON。不過無所謂了,正確輸出HTTP回應GZip數據中的結果,就是我們想要的。

 

注意可以通過HttpClient類型的EnsureSuccessStatusCode來確保HTTP回應返回狀態成功,否則會拋出異常。

//確保HTTP成功狀態值(response對應HttpResponseMessage對象)

response.EnsureSuccessStatusCode();

 

上述API使用了一個顯示參數來指定需要返回GZIP數據回應,也可以通過設置HTTP請求的AcceptEncoding,如下,手動加入GZIP類型:

//+ System.Net.Http;

//+ System.Net.Http.Headers

 

//http是HttpClient對象

//也可以手動構建HttpRequestMessage,然后通過HttpClient.SendAsync來發送

http.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("GZIP"));

http是HttpClient對象,它的DefaultRequestHeaders返回HttpRequestHeaders對象。當然也可以手動構建HttpRequestMessage然后修改HttpRequestHeaders,然后通過HttpClient.SendAsync來發送。另外注意StringWithQualityHeaderValue類型在System.Net.Http.Headers命名空間內。


免責聲明!

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



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