只有累積,沒有奇蹟

2018年10月19日 星期五

[C#] Web API - HttpClient 入門

HttpClient 介紹
當在開發 Client 程式時,要取得呈現在畫面上的資料會與 API / Server 進行連線動作,在過去可以使用 WebClient 或者是 HttpWebRequest ,在 .NET Framework 4.5 開始微軟提供 HttpClient 類別給開發者使用命名空間為 Sysyem.Net.Http,它提供靈活且可擴充的 API 來訪問 HTTP 公開的物件,發送 Request 跟接收回傳的 Response 主要是透過 HttpRequestMessage HttpResponseMessage 這兩個類別,透過 Content 屬性取得 HTTP 回傳內容與訊息;工作原理可以參考下圖
HttpClient 與 WebClient 和 HttpWebRequest 相比,有以下幾點值得注意的地方

1. HttpClient 實現允許默認標題 (default headers) 被設置並應用於所有請求,取消未完成請求
2. 可以透過單一 HttpClient instance 發送多個請求
3. HttpClient instance 不會與 Http Server 或是 Host綁定,也就是說可以使用相同 HttpClient 向 www.a.com 與 www.b.com 發送 request
4. HttpClient 使用新的工作式非同步模式 (TAP) 來處理非同步請求,處理與管理未完成請求變得較為容易

使用方式 
HttpClient 提供多個非同步方法取得 HTTP 內容,有 GET / POST / PUT / DELETE...等
以下為使用 HttpClient 進行 HTTP GET請求的範例程式 -> 這裡使用的是國家城市資訊的 geonames API

方式 1 - using GetAsync 

namespace HttpClientSample
{
    class Program
    {
 private const string uri = "http://api.geonames.org/search";

 static void Main(string[] args)
 {
  Run();

  Console.WriteLine("Hit enter to exit...");
  Console.ReadKey();
 }

 static async void Run()
 {
  using (HttpClient client = new HttpClient())
  {
   try
   {
                                client.Timeout = TimeSpan.FromSeconds(30);
    HttpResponseMessage response = await client.GetAsync(uri);
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();

    Console.WriteLine(responseBody);
   }
   catch (HttpRequestException e)
   {
    Console.WriteLine("\nException Caught!");
    Console.WriteLine("Message :{0} ", e.Message);
   }
  }    
 }
    }
}

程式說明 : 
  • Line 17 : 建立 HttpClient用 using包起來確保物件使用後資源可以被完整釋放掉
  • Line 21 : 設定 Timeout 屬性,避免資源浪費
  • Line 22 : 透過 HttpClient GetAysnc 方法發送非同步請求 HTTP Get Request 到目標 uri,並將目標uri Response 結果存放在 HttpResponseMessage 
  • Line 23 , 28 : EnsureSuccessStatusCode 如果 Status Code 不為 2xx,會丟出HttpRequestException,會進到 Catch 處理寫 error log message
  • Line 24 , 26 : 非同步的方式取得 HTTP Response 的 Content,並 print 出來
執行結果 : 
  • 使用非同步方法,會先輸出 print Hit enter to exit.
  • 紅色框框部分為 uri 回傳內容

方式 2 - using SendAsync 

static async Task RunSendAsync()
{
 using (HttpClient client = new HttpClient())
 {
  HttpRequestMessage httpRequest = new HttpRequestMessage(HttpMethod.Get, uri);

  await client.SendAsync(httpRequest)
   .ContinueWith(responseTask =>
   {
    Console.WriteLine("Response: {0}", responseTask.Result);
   });
 }   
}
程式說明 : 
  • Line 5 : 建立 HttpRequestMessage instance並指定HTTP Method 為 GET 和呼叫的 Uri
  • Line 7 : 透過 SendAysnc 方法將 HttpRequestMessage 內容作為參數發送非同步請求
  • Line 8 : 任務完成後要做的事情,類似 Javascript 中使用 Promise 處理非同步的寫法
  • Line 10 : 將 HTTP Response 結果印出來
執行結果 : 

HttpClient v.s WebClient 
在蒐集資訊過程中看到 stackoverflow 有篇文章 在討論兩者的比較
小弟針對有回答得大大做個小整理,如果有遺漏或是誤解請各位大大告知
  • HttpClient 是新的 API,對於非同步處理是優於 WebClient 
  • HttpClient 比 WebClient 更接近 HTTP
  • HttpClient 沒有要取代 WebClient,像是 WebClient 就支援 FTP 而 HttpClient 不支持
  • HttpClient 適用於 .Net Framework 4.5以上非同步功能WebClient 使用上簡單和簡潔
  • RestSharp 結合 HttpWebRequest 簡單好使用 (列入研究清單 !!! )

參考
HttpClient 類別
Deciding between HttpClient and WebClient
WebClient vs HttpClient vs HttpWebRequest
HttpClient is Here
使用 HttpClient 來存取 GET,POST,PUT,DELETE,PATCH 網路資源
C# HttpClient WebAPI : 2. 最簡單的方式使用 HttpClient 類別
理解并使用.NET 4.5中的HttpClient

5 則留言:

  1. 你好~想請教第一張圖片那種方塊流程圖的風格是用什麼軟體編輯的呢

    回覆刪除
    回覆
    1. 不好意思晚回覆了, 軟體是 balsamiq 網站可以參考 https://balsamiq.com/ :)

      刪除
  2. HttpClient 不要搭配 using() 使用, 否則在大量使用的情況下, 連線會被佔滿
    細節請參考:
    https://blog.darkthread.net/blog/httpclient-sigleton/

    回覆刪除

Copyright © m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com