1. 程式人生 > >Asp.Net Web API(二)

Asp.Net Web API(二)

default exceptio 服務器 路由 回復 事情 http響應 images art

技術分享創建一個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(二)