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類中進行設定路由。