Asp.Net Web API(二)
創建一個Web API項目
第一步,創建以下項目
當然,你也可以創建一個Web API項目,利用 Web API模板,Web API模板使用 ASP.Net MVC提供API的幫助頁。
添加Model
一個模型就是在你的應用程序中展示數據的一個對象。ASP.NET Web API 可以自動序列化你的模型到JSON,XML或一些其它格式,然後把已序列化的數據寫入到HTTP響應消息的正文。只要客戶端可以讀取序列化的數據,那麽它同樣可以反序列這個對象。大多數的客戶端都可以解析JSON或XML。此外,客戶端可以聲明它想要通過HTTP請求消息中設置的接收標頭的那種格式。
然後我們在Models目錄下創建一個簡單的展示商品的Model
namespace WebAPIDemo.Models { public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } } }
添加Repository
首先我們需要存儲產品的集合,分開手機我們的服務是一個好主意,這種方式,我們可以改變後備存儲,而不用修改服務器的實現,這種模型的設計叫做倉儲模型,首先建立一個接口
namespace WebAPIDemo.Models { public interface IProductRepository { IEnumerable<Product> GetAll(); Product Get(int id); Product Add(Product item); void Remove(int id); bool Update(Product item); } }
暫時我們把接口和實現類放在一個目錄下,現在在Models目錄下添加另外一個類,這個類將實現IProductRepository接口
1 namespace WebAPIDemo.Models 2 { 3 public class ProductRepository : IProductRepository 4 { 5 private List<Product> products = new List<Product>(); 6 private int _nextId = 1; 7 public ProductRepository() 8 { 9 Add(new Product { Name = "一加5", Category = "一加", Price = 2999 }); 10 Add(new Product { Name = "小米pro", Category = "小米", Price = 5599 }); 11 Add(new Product { Name = "一加X", Category = "一加", Price = 1499 }); 12 } 13 public Product Add(Product item) 14 { 15 if (item == null) 16 throw new ArgumentNullException("item"); 17 item.Id = _nextId++; 18 products.Add(item); 19 return item; 20 } 21 22 public Product Get(int id) 23 { 24 return products.Find(y => y.Id == id); 25 } 26 27 public IEnumerable<Product> GetAll() 28 { 29 return products; 30 } 31 32 public void Remove(int id) 33 { 34 products.RemoveAll(y => y.Id == id); 35 } 36 37 public bool Update(Product item) 38 { 39 if (item == null) 40 throw new ArgumentNullException("item"); 41 int index = products.FindIndex(y => y.Id == item.Id); 42 if (index < 0) 43 return false; 44 products.RemoveAt(index); 45 products.Add(item); 46 return true; 47 } 48 } 49 }
添加Controller
在ASP.NET Web API中,控制器就是一個處理HTTP請求的對象。我們將添加一個控制器,它即可以返回一個商品的列表數據,也可以通過產品編號返回單個產品信息。
註意,如果你使用了ASP.NET MVC 已熟悉控制器,Web API控制器類似於MVC控制器,但是繼承ApiController,而不是Controller類
1 namespace WebAPIDemo.Controllers 2 { 3 public class ProductController : ApiController 4 { 5 static IProductRepository repository= new ProductRepository(); 6 } 7 }
添加CRUD的基本操作方法
第一個:得到所有產品信息列表,在控制器中添加方法如下
1 public IEnumerable<Product> GetProducts() 2 { 3 return repository.GetAll(); 4 }
這個方法是以Get開頭,所以通過約定映射Get請求,此外,因為不包含參數,它映射一個不包含在路徑中的id字段的URI
第二個方法:通過產品編號獲取一個產品信息,在控制器添加方法如下
1 public Product GetProduct(int id) 2 { 3 var item = repository.Get(id); 4 if (item == null) 5 //未找到拋出一個404的狀態碼異常 6 throw new 7 HttpResponseException(HttpStatusCode.NotFound); 8 return item; 9 }
這個方法的名稱是以Get開頭但這個方法有一個名字為id的參數。這個參數被映射到URI路徑中的id字段。這個Asp.Net Web API框架自動把id參數轉換為正確的int數據類型,如果id無效,就會拋出一個HttpResponseException異常。此異常將有框架轉換成一個404錯誤。
第三個:按照類型查找產品信息,在控制器中添加方法如下
1 public IEnumerable<Product> GetProductsByCategory(string category) 2 { 3 return repository.GetAll().Where(y => String.Equals(y.Category, category, StringComparison.OrdinalIgnoreCase)); 4 }
如果請求的URI中包含查詢字符串,這個Web API試圖在控制器方法的參數中來匹配查詢字符串。因此,窗體中“api/products?category=category”的URI將映射到此方法。
第四個:添加一個新產品,在控制器添加的方法如下
1 public Product PostProduct(Product item) 2 { 3 item = repository.Add(item); 4 return item; 5 }
請註意這個方法的兩個事情:
這個方法的名字以“Post”開頭,為了創建一個新產品,這個客戶端將發送一個HTTP Post請求。這個方法采用類型為Product的參數。在Web API中復雜類型的參數是從請求消息體中反序列化得到的,因此,我們期待客戶端發送XML或JSON格式的一個產品對象的序列號表現形式
此實現會工作,但它還很不完整。理想情況下,我們希望的HTTP響應。包含以下內容:
響應代碼:在默認情況下,這個Web API框架設置響應狀態碼為200(OK)。但是根據這個HTTP/1.1協議,當POST請求在創建一個資源時,這個服務端應該回復狀態201(Created)。位置:當服務端創建一個資源時,它應該在響應的Location標頭中包含這個資源的URI。
ASP.NET Web API使它容易操作HTTP響應消息。這個改善後的代碼:
public HttpResponseMessage PostProduct(Product item) { item = repository.Add(item); //創建返回對象HttpResposeMessage並將回復狀態設置為201. HttpResponseMessage respose = Request.CreateResponse<Product>(HttpStatusCode.Created, item); String uri = Url.Link("DefaultApi", new { id = item.Id }); //設置HttpResposeMessage標頭中Locaion respose.Headers.Location = new Uri(uri); return respose; }
請註意:此方法返回類型現在是HttpResponseMessage。通過返回HttpResponseMessage而不是產品,我們可以控制HTTP響應消息,包括狀態代碼和位置標頭的詳細信息。
CreateResponse方法將會創建HttpResponseMessage,並自動將Product對象序列化表示形式寫入到響應消息的正文中。
第四個:通過PUT更新產品
1 public void PutProduct(int id,Product product) 2 { 3 product.Id = id; 4 if(!repository.Update(product)) 5 throw new HttpResponseException(HttpStatusCode.NotFound); 6 }
方法名稱以Put開頭,這樣Web API就能夠將其與PUT請求相匹配。這個方法有兩個參數,一個是產品id和更新的產品,id參數是從URI中獲得的,product參數是從請求正文反序列化得來的。默認情況下,ASP.NET Web API框架從路由獲取簡單的參數類型,從請求正文獲取復雜的類型。
第五個方法:刪除產品,在控制器添加代碼如下。
1 public void DeleteProduct(int id) 2 { 3 Product item = repository.Get(id); 4 if (item == null) 5 throw new HttpResponseException(HttpStatusCode.NotFound); 6 repository.Remove(id); 7 }
如果刪除成功,它可以返回狀態200(OK)與實體的描述該狀態;如果刪除依然掛起,則返回狀態202(已接受);或狀態與沒有實體正文204(無內容)。在這種情況下,DeleteProduct方法具有void返回類型,因此ASP.NET Web API自動轉換此狀態代碼204(無內容)
運行測試
方法創建完畢後我們就可以運行服務端進行測試了
上述測試我們發現我們的路由只是“api/{controler}”就成功返回了GetProducts方法中的數據,這也是ASP.NET Web API與ASP.NET MVC 之間的區別。Web API路由可以沒有{Action},只通過HTTP請求方式來匹配路由,並且路由默認以api啟示,如果想要設置,在App_Start中WebApiConfig類中進行設置路由。
Asp.Net Web API(二)