標籤:
Asp.Net Web API 導航
Asp.Net Web API第一課——入門http://www.cnblogs.com/aehyok/p/3432158.html
Asp.Net Web API第二課——CRUD操作http://www.cnblogs.com/aehyok/p/3434578.html
前言
本教程示範從一個控制台應用程式,使用HttpClient調用Web API。我們也將使用上一個教程中建立的Web API。你可以直接在http://www.cnblogs.com/aehyok/p/3434578.html這篇文章中找到相應的下載連結,就可以獲得建立的Web API。
我們還是通過VS2013建立的測試專案。本教程範例程式碼下載連結http://pan.baidu.com/s/1mrObX
建立控制台項目
首先建立一個簡單的控制台應用程式,然後通過Nuget來獲得Microsoft.AspNet.WebApi.Client。
通過搜尋,然後點擊安裝即可安裝Web API 用戶端庫。
在項目中添加Model
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CallWebApi{ public class Product { public string Name { get; set; } public double Price { get; set; } public string Category { get; set; } }}
這個類建立了一個資料對象,HTTPClient可以在HTTP 要求本文中寫入它,也可以從HTTP響應本文中讀取它。
初始化HTTPClient
建立一個新的HttpClient樣本,如下所示:
using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; namespace CallWebApi{ class Program { static void Main(string[] args) { HttpClient client = new HttpClient(); client.BaseAddress = new Uri("http://localhost:4115/"); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); } }}
這是上一教程中的應用程式執行效果展示
所以我們上面的代碼
client.BaseAddress = new Uri("http://localhost:4115/");
然後添加了一個json格式的接受表頭。它告訴要以 JSON 格式發送資料的伺服器接受標題。
通過Http Get方法來擷取資源
下面的代碼就是,如何通過API來查詢產品資訊列表。
HttpResponseMessage response = client.GetAsync("api/products").Result; if (response.IsSuccessStatusCode) { var products = response.Content.ReadAsAsync<IEnumerable<Product>>().Result; foreach (var p in products) { Console.WriteLine("{0}\t{1};\t{2}", p.Name, p.Price, p.Category); } } else { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); }
這個GetAsync方法發送了一個Http Get請求。顧名思義,這個GetAsync方法是非同步。它立即返回,無需等待服務端的響應。這個傳回值表示一個非同步作業的Task對象。當這個操作完成的時候,這個Task.Result屬性包含HTTP響應。
如果 HTTP 響應指示成功,這個響應本文將包含一個JSON格式的產品資訊列表。為瞭解析這個列表,需要調用ReadAsAsync。這個方法讀取響應本文並且試圖範序列化到一個指定的CLR類型。這個方法也是非同步, 因為這個響應的本文可以是任意大的。
api/products的請求標題
api/products的響應標題
api/products的響應本文
最終調用結果在控制台的展示如下
通過一個產品ID獲得一個產品資訊
///通過一個產品ID獲得一個產品資訊 response = client.GetAsync("api/products/1").Result; if (response.IsSuccessStatusCode) { var product = response.Content.ReadAsAsync<Product>().Result; Console.WriteLine("{0}\t{1};\t{2}", product.Name, product.Price, product.Category); } else { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); }
媒體類型格式化標識
ReadAsAsync是在System.Net.Http.HttpContentExtensions類中定義的擴充方法。不帶參數,它用預設的媒體類型格式標識設定試圖去解析這個響應本文。這個預設的格式標識支援JSON、XMl和Form-url-encoded data。
你可以明確的指定媒體類型格式標識來使用。這是非常有用的如果你有一個自訂的媒體類型格式標識。
var formatters = new List<MediaTypeFormatter>() { new MyCustomFormatter(), new JsonMediaTypeFormatter(), new XmlMediaTypeFormatter()};resp.Content.ReadAsAsync<IEnumerable<Product>>(formatters);
通過HTTP Post添加一個資源
下面的代碼就是發送了一個包含Json格式的Product實體的Post請求。
///HTTP Post請求 var gizmo = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" }; Uri gizmoUri = null; response = client.PostAsJsonAsync("api/products", gizmo).Result; if (response.IsSuccessStatusCode) { gizmoUri = response.Headers.Location; } else { Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase); }
PostAsJsonAsync 是在System.Net.Http.HttpContentExtensions類中定義的擴充方法。它等效於一下內容:
var product = new Product() { Name = "Gizmo", Price = 100, Category = "Widget" }; MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter(); HttpContent content = new ObjectContent<Product>(product, jsonFormatter); var resp = client.PostAsync("api/products", content).Result;
對於XML格式的類型,使用這個PostAsXmlAsync方法。
預設情況下,這個JSON格式表示設定Content-type為“application/json”。你也能明確的指定一個媒體類型。例 如: "application/vnd.example.product" 是你的Product實體的媒體類型。你可以設定媒體類型如下:
HttpContent content = new ObjectContent<Product>(product, jsonFormatter, "application/vnd.example.product+json");
通過HTTP PUT修改一個資源
下面的代碼是發送一個PUT請求(接著上面添加的實體進行修改)
gizmo.Price = 99.9; response = client.PutAsJsonAsync(gizmoUri.PathAndQuery, gizmo).Result; Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
這個PutAsJsonAsync方法像PostAsJsonAsync一樣工作,除了它發送一個PUT請求來代替POST之外。
通過HTTP DELETE刪除一個資源
到了現在,你可以能夠預測怎樣發送一個DELETE請求。
///刪除一個資源 response = client.DeleteAsync(gizmoUri).Result; Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
和GET一樣,刪除請求並沒有一個請求本文,所以你不需要指定 JSON 或 XML 格式。
Error錯誤處理
HTTPClient不會拋出一個異常,當它接收到一個錯誤碼的HTTP響應。取而代之的是,這個響應的這個狀態代碼屬性中包含這個狀態代碼。此外, 如果狀態是成功碼 (200-299 範圍中的狀態碼),IsSuccessStatusCode屬性為true。
上面的例子中我們有使用這個模式:
HttpResponseMessage response = client.GetAsync("api/products").Result; if (response.IsSuccessStatusCode){ // .... }
如果你更喜歡將錯誤碼視為異常來看的話,調用這個EnsureSuccessStatusCode方法。如果這個響應狀態不是一個成功的狀態代碼,那麼這個方法就會拋出一個異常。
try { var resp = client.GetAsync("api/products").Result; resp.EnsureSuccessStatusCode(); // Throw if not a success code. // ... } catch (HttpRequestException e){ Console.WriteLine(e.Message);}
配置HttpClient
如果要配置HttpClient,就建立一個WebRequestHandler執行個體,設定它的屬性並將它傳遞給HttpClient建構函式:
WebRequestHandler handler = new WebRequestHandler(){ AllowAutoRedirect = false, UseProxy = false };HttpClient client = new HttpClient(handler);
WebRequestHandler從HttpMessageHandler派生。您還可以通過從HttpMessageHandler派生插入自訂訊息處理常式中。有關詳細資料,請參閱HTTP訊息處理常式(暫未實現)
總結
本文來源連結http://www.asp.net/web-api/overview/web-api-clients/calling-a-web-api-from-a-net-client
一步一步的學下來,還是很有收穫的。其中有些地方不太理解還需要慢慢的消化了。
Asp.Net Web API 2第三課——.NET用戶端調用Web API