[C#][ASP.NET Web API 2] 使用 Web API 實作具有 CRUD 的 RESTful 服務

[C#.NET][Web API] 使用 Web API 實作具有 CRUD 的 RESTful 服務

續上篇 http://www.dotblogs.com.tw/yc421206/archive/2013/11/06/127047.aspx,簡易實作了 Web API(跟本啥都沒做) 後接下來要來實作 CRUD 功能

測試工具

Chrmoe’s Postman

實作步驟

Step1.新增 Model

Step2.新增 Control

Step3.測試 POST

Step4.測試 Get

Step5.測試 Put

Step6.測試 Delete

 


Step1.新增Model

在 Model 資料夾增加以下類別

IProductRepository 用來介接不同的資料庫型態,可用來實作 IoC 的的介面。

ProductRepository 用來模擬跟實際資料存取的類別。

詳細內容請參考首席架構師 Clark 的文章,http://www.dotblogs.com.tw/clark/archive/2012/04/29/71883.aspx

 


{
    public string ISBN { get; set; }

    public string AuthiorName { get; set; }

    public string BookName { get; set; }

    public string Category { get; set; }

    public decimal Price { get; set; }
}

 

{
    IEnumerable<Product> GetAll();

    Product Get(int id);

    Product Get(string ISBN);

    Product Get(decimal Price);

    bool Post(Product item);

    bool Delete(string ISBN);

    bool Put(string ISBN, Product item);
}

 
Repository : IProductRepository
{
    private List<Product> _productList = new List<Product>();

    public ProductRepository()
    {
        this._productList.Add(new Product() { ISBN = "9787302273578", BookName = "Visual Studio2010高級編程", AuthiorName = "(美)蘭多夫|譯者:任鴻//普傑//高宇輝", Category = ".NET", Price = 128 });
        this._productList.Add(new Product() { ISBN = "9787111412304", BookName = "Windows Phone8開發技巧與案例精解", AuthiorName = "周家安", Category = ".NET", Price = 69 });
        this._productList.Add(new Product() { ISBN = "9787111385448", BookName = "編寫可讀代碼的藝術", AuthiorName = "(美)鮑斯維爾//富歇|譯者:尹哲//鄭秀雯", Category = "Project", Price = 59 });
        this._productList.Add(new Product() { ISBN = "9787111379331", BookName = "Android開發寶典(附光碟)/程序員開發寶典系列", AuthiorName = "王國輝//李偉 ", Category = "Android", Price = 79 });
    }

    public IEnumerable<Product> GetAll()
    {
        return this._productList;
    }

    public Product Get(string ISBN)
    {
        if (string.IsNullOrEmpty(ISBN))
        {
            throw new ArgumentNullException("ISBN");
        }
        return this._productList.Find(p => p.ISBN == ISBN);
    }

    public Product Get(int id)
    {
        return this._productList[id];
    }

    public Product Get(decimal Price)
    {
        return this._productList.Find(p => p.Price == Price);
    }

    public bool Post(Product item)
    {
        if (item == null)
        {
            throw new ArgumentNullException("item");
        }
        var query = (from product in this._productList
                     where product.ISBN == item.ISBN
                     select product).FirstOrDefault();

        if (query == null)
        {
            this._productList.Add(item);
            return true;
        }
        else
        {
            return false;
        }
    }

    public bool Delete(string ISBN)
    {
        if (string.IsNullOrEmpty(ISBN))
        {
            throw new ArgumentNullException("ISBN");
        }

        this._productList.RemoveAll(p => p.ISBN == ISBN);
        return true;
    }

    public bool Put(string ISBN, Product item)
    {
        if (item == null)
        {
            throw new ArgumentNullException("item");
        }

        var query = (this._productList.Where(product => product.ISBN == ISBN)).FirstOrDefault();

        if (query == null)
        {
            return false;
        }
        else
        {
            query.AuthiorName = item.AuthiorName;
            query.BookName = item.BookName;
            query.Category = item.BookName;
            query.Price = item.Price;
            return true;
        }
    }
}

 

PS.這裡的寫法主要是要模擬資料庫的讀寫,寫法不是重點,你也可以不必像我這樣做,這只是個人習慣問題而已

Step2.新增 Controller

image

 

SNAGHTML3143dea

 

ProductsController 繼承了 ApiController,要有 CRUD 我們還得實作 Http 的四個動詞 ,有兩個方式

1.GET、POST、PUT、DELETE,方法名稱帶有這些動詞前綴

2.在方法體標上特性(Atturibute),[HttpGet]、[HttpPost]、[HttpPut]、[HttpDelete],可參考首席神人 小朱 的文章:http://www.dotblogs.com.tw/regionbbs/archive/2013/01/10/web.api.method.and.routing.aspx

 

PS.若一個類別裡有多個 Get 參數定義又一樣的話,還要再定義 Route

 

在這裡我直接拿 IProductRepository 來實作,延用規範

sController : ApiController
{
    private static readonly IProductRepository s_Repository = new ProductRepository();
    
    public IEnumerable<Product> GetAll()
    {
        return s_Repository.GetAll();
    }

    public Product Get(int id)
    {
        return s_Repository.Get(id);
    }

    public Product Get(string ISBN)
    {
        return s_Repository.Get(ISBN);
    }

    public Product Get(decimal Price)
    {
        return s_Repository.Get(Price);
    }

    public bool Post(Product item)
    {
        return s_Repository.Post(item);
    }

    public bool Put(string ISBN, Product item)
    {
        return s_Repository.Put(ISBN, item);
    }

    // DELETE api/products/5
    public bool Delete(string ISBN)
    {
        return s_Repository.Delete(ISBN);
    }

}

 

簡單測試

image

 

 

 

 

Step3.測試 POST

設定好參數後,按下send,回傳true

SNAGHTML5674c63

 

 

再按一次應該要回傳 false

SNAGHTML538606d

 

Step4.測試 Get

調用 Get(int id),直接在URL代引數(好像就只有 int 型別可以這樣用)

SNAGHTML587cbb9

 

調用 Get(string ISBN)

SNAGHTML567f6ec

 

調用 Get(decimal Price)

SNAGHTML565f213

Step5.測試 Put

當我們的參數型態是 class 時,要用x-www-form-urlencoded,其他的則用URL params(除了 int 應該可以不用)

SNAGHTML56e9169

 

 

帶出來的資料長這樣,第一個參數要 Query String,而不是Body

SNAGHTML56f72b1

 

 

 

Step6.測試 Delete

SNAGHTML57c9c04

 


文章出自:http://www.dotblogs.com.tw/yc421206/archive/2013/11/07/127108.aspx

範例下載:http://yunpan.cn/Q98yuJ66ZSYtR

 

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo