[Web API] WinForm 使用 HttpClient 呼叫 Web API

簡單介紹 HttpClient 類別與該如何於 Windows Form 中使用 HttpClient 類別呼叫 Web API 的服務。

前言


  之前幾篇文章已經介紹了 Web 與 Web API 的使用方式,接下來將介紹如何在 Windows Form 呼叫 Web API 的方法,要在 WinForm 中使用 Web API 的話,除了可以使用舊有的 WebClient、HttpWebRequest 類別之外,還可以使用新的 HttpClient 類別進行操作,HttpClient 類別是包含在 .Net Framework 4.5 中的 System.Net.Http 之命名空間底下,HttpClient 類別一般來說需要在 .Net Framework 4.5 上才能夠使用,但是如果有裝 NuGet 的話,可以使用 NuGet 搜尋 Microsoft.Net.Http,NuGet 有提供 4.0 可以使用的安裝包。

 

HttpClient 簡介


  在開始使用 WinForm 操作 Web API 前先來介紹一下 HttpClient 類別,HttpClient 類別主要使用於發送 HTTP 要求與接收 HTTP 回應內容,其中包含了一個特點,就是使用非同步方式發送 GET、POST、PUT、DELETE 要求,在 MSDN HttpClient 類別文件中提到,使用 HttpClient 的每個請求都擁有各自的連接集區,每個連接集區並不會互相干擾,意思就是可以使用一個實體化的 HttpClient 物件發送給各個不同的 HTTP 服務而不會相互影響。

 

  HttpClient 能夠自訂自己的 HttpClient Handler,需要透過繼承 DelegatingHandler 的方式並覆寫其 SendAsync 方法,參考此 HttpClient Message Handlers 文章提到,通常一個服務程序接收到了一個請求並處理其相關內容再回覆結果,而過程中可能會經過數個 Handler 層層傳遞,這種處理模式稱為 Delegating Handler,如下圖:

 

  在客戶端 HttpClient 透過消息處理程序來處理請求時,默認使用的是 HttpClientHandler 發送請求並得到服務回應,所以我們可以在此將自訂的 Message Handler 插入到 HttpClient 與服務之間,如下圖,但是在這裡不特別說明作法,可以參考 [Web API] 自定 HTTP Message Handlers 此篇,另外對於 Web API 也能夠自訂Http Message Handler。

 

使用 HttpClient


  經過以上描述應該對於 HttpClient 有了大概的瞭解,接下來就來在 Windows Form 裡使用 HttpClient 類別操作呼叫 Web API 吧,同樣使用前幾篇建立好的 Web API 做為基底然後再加入一個視窗應用程式,如下圖步驟

 

  再來因為 Web API 使用到 JSON 格式,所以透過 NuGet 安裝 Json.Net 幫助我們處理 JSON 格式資料。

 

  接下來接可以加入一個 Windows Form,簡單的把要使用的控制箱加入後切換到程式碼檢視,準備開始撰寫相關代碼。

 

  在開始撰寫代碼之前要先注意一件事,由於先前有提到,HttpClient 類別提供的 GET、POST、PUT、DELETE 方法都是非同步方法,所以我們在實際上要去執行 HttpClient 操作的方法上必須加入 asyncawait 關鍵字,詳細可以參考 使用 Async 和 Await 設計非同步程式 (C# 和 Visual Basic) 文章。

 

  例如當需要取得 Web API 的所有產品清單時,就可以撰寫  GetAllProducts() 方法,如下

private async void GetAllProducts()
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.GetAsync("http://localhost:49988/api/products");
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();
    ShowResult(JsonConvert.DeserializeObject<List<Product>>(responseBody));
}

 

  在以上方法中可以看到於方法宣告中加入了 async 宣告此方法為非同步方法,之後產生了 HttpClient 物件,並透過該物件的 GetAsync(string) 方法使用非同步作業要求取得此 URI 資源,GetAsync(string) 方法將發送一個 GET 請求至 Web API 服務並返回結果,這裡可以注意到在 client.GetAsync(URL) 前面加了一個 await 關鍵字,其原因在於 HttpClient 是非同步方法,所以必須要求等待到資料處理完成返回後才能繼續下面的步驟,如果不加 await 關鍵字於前方,GetAsync(string) 方法預設是返回一個 Task<TResult> 的型別。

 

  而如需要使用 POST 動詞的方式呼叫 Web API,就需要改使用 PostAsync(string, httpContent) 方法,如下

private async void PostProduct()
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.PostAsync("http://localhost:49988/api/products/ASP.NET/WEB/399/12", null);
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();
    ShowResult(JsonConvert.DeserializeObject<List<Product>>(responseBody));
}

 

  在以上方法中使用 PostAsync(string, httpContent) 方法處理 Post 傳輸,在此 HttpContent 參數為 null 的原因在此 Web API 的服務是使用 URI 資源的形式,會將參數都至於此 URI 位置中,所以當不是使用此方式的情況下,就必須要自行將參數寫入 HttpContent。

 

  而 Put、Delete 就如同上述內容一樣做法,如下

private async void PutProduct()
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.PutAsync("http://localhost:49988/api/products/1/The WebAPI/MVC/450/5", null);
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();
    ShowResult(JsonConvert.DeserializeObject<List<Product>>(responseBody));
}

private async void DeleteProductById()
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.DeleteAsync("http://localhost:49988/api/products/2");
    response.EnsureSuccessStatusCode();
    string responseBody = await response.Content.ReadAsStringAsync();
    ShowResult(JsonConvert.DeserializeObject<List<Product>>(responseBody));
}

 

  參考以上內容完成後,就可以來測試一下,如下

 

  以上就是一個 Windows Form 使用 HttpClient 呼叫 Web API 的使用範例,如有任何遺漏或錯誤,日後將繼續修正補充。

 

範例程式碼


TWebApi_03.part01.rar

TWebApi_03.part02.rar

TWebApi_03.part03.rar

 

參考資料


HttpClient 類別

HttpMessageHandler 類別

使用 Async 和 Await 設計非同步程式 (C# 和 Visual Basic)

HttpClient Message Handlers

HTTP Message Handlers

ASP.NET WEB API 心得筆記 (9) 簡介 SYSTEM.NET.HTTP.HTTPCLIENT 類別

 

 


以上文章敘述如有錯誤及觀念不正確,請不吝嗇指教
如有侵權內容也請您與我反應~謝謝您 :)