第 3 部分:建立管理員控制器
作者:Rick Anderson
新增管理員控制器
在本節中,我們將新增支援 CRUD (建立、讀取、更新和刪除) 作業的 Web API 控制器。 控制器會使用 Entity Framework 與資料庫層通訊。 只有系統管理員才能使用此控制器。 客戶會透過另一個控制器存取產品。
在方案總管中,以滑鼠右鍵按一下 Controllers 資料夾。 選取 [新增],然後 [控制器]。
在 [新增控制器] 對話方塊中,命名控制器 AdminController
。 在 [範本],選取 [使用 Entity Framework,具有讀取/寫入動作的 API 控制器]。 在 [模型類別] 下,選取 [產品 (ProductStore.Models)]。 在 [資料內容] 下,選取 [<新的資料內容>]。
注意
如果 [模型類別] 下拉式清單未顯示任何模型類別,請確定您已編譯專案。 Entity Framework 會使用反映,因此需要編譯的組件。
選取 [<新的資料內容>] 將會開啟 [ 新的資料內容 ] 對話方塊。 將資料內容命名為 ProductStore.Models.OrdersContext
。
按一下 [確定] 以關閉 [新的資料內容] 對話方塊。 在 [新增控制器] 對話方塊中,按一下 [新增]。
以下是專案新增的內容:
- 包含名為
OrdersContext
的類別,該類別衍生自 DbContext。 這個類別是 POCO 模型與資料庫之間的連結。 - 名為
AdminController
的 Web API 控制器。 此控制器支持Product
執行個體上的 CRUD 作業。 它會使用OrdersContext
類別與 Entity Framework 通訊。 - Web.config 檔案中的新資料庫連結字串。
開啟 OrdersContext.cs 檔案。 請注意,建構函式會指定資料庫連結字串的名稱。 此名稱是指已新增至 Web.config 的連接字串。
public OrdersContext() : base("name=OrdersContext")
將下列屬性新增至 OrdersContext
類別:
public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }
DbSet 代表一組可以查詢的執行個體。 以下是 OrdersContext
類別的完整清單:
public class OrdersContext : DbContext
{
public OrdersContext() : base("name=OrdersContext")
{
}
public DbSet<Order> Orders { get; set; }
public DbSet<OrderDetail> OrderDetails { get; set; }
public DbSet<Product> Products { get; set; }
}
AdminController
類別會定義五個實作基本 CRUD 功能的方法。 每個方法都會對應至用戶端可以叫用的 URI:
控制器方法 | 描述 | URI | HTTP 方法 |
---|---|---|---|
GetProducts | 獲取所有產品。 | api/products | GET |
GetProduct | 依照識別碼找到產品。 | api/products/id | GET |
PutProduct | 更新產品。 | api/products/id | PUT |
PostProduct | 建立新的產品。 | api/products | POST |
DeleteProduct | 刪除產品。 | api/products/id | DELETE |
每個方法都會呼叫 OrdersContext
來查詢資料庫。 修改集合的方法 (PUT、POST 和 DELETE) 呼叫 db.SaveChanges
,以保存資料庫的變更。 控制器是根據 HTTP 要求而建立的,然後會棄置,因此必須在方法傳回之前保存變更。
新增資料庫初始設定式
Entity Framework 有一個很好的功能,可讓您在啟動時填入資料庫,並在模型變更時自動重新建立資料庫。 這項功能在開發期間很有用,因為即使您變更模型,您一律都有一些測試資料。
在 [方案總管] 中,以滑鼠右鍵按一下 [模型] 資料夾,然後建立新類別,名為 OrdersContextInitializer
。 貼入下列實作:
namespace ProductStore.Models
{
using System;
using System.Collections.Generic;
using System.Data.Entity;
public class OrdersContextInitializer : DropCreateDatabaseIfModelChanges<OrdersContext>
{
protected override void Seed(OrdersContext context)
{
var products = new List<Product>()
{
new Product() { Name = "Tomato Soup", Price = 1.39M, ActualCost = .99M },
new Product() { Name = "Hammer", Price = 16.99M, ActualCost = 10 },
new Product() { Name = "Yo yo", Price = 6.99M, ActualCost = 2.05M }
};
products.ForEach(p => context.Products.Add(p));
context.SaveChanges();
var order = new Order() { Customer = "Bob" };
var od = new List<OrderDetail>()
{
new OrderDetail() { Product = products[0], Quantity = 2, Order = order},
new OrderDetail() { Product = products[1], Quantity = 4, Order = order }
};
context.Orders.Add(order);
od.ForEach(o => context.OrderDetails.Add(o));
context.SaveChanges();
}
}
}
繼承自 DropCreateDatabaseIfModelChanges 類別,每當修改模型類別時,我們會告知 Entity Framework 卸除資料庫。 當 Entity Framework 建立 (或重新建立) 資料庫時,它會呼叫植入方法來填入資料表。 我們使用植入方法新增一些範例產品加上範例訂單。
這項功能非常適合用於測試,但請勿在生產環境中使用 DropCreateDatabaseIfModelChanges 類別,因為如果有人變更模型類別,可能會遺失您的資料。
接下來,開啟 Global.asax,並將下列程式碼新增至 Application_Start 方法:
System.Data.Entity.Database.SetInitializer(
new ProductStore.Models.OrdersContextInitializer());
將要求傳送至控制器
此時,我們尚未撰寫任何用戶端程式碼,但您可以使用網頁瀏覽器或 Fiddler 之類的 HTTP 偵錯工具叫用 Web API。 在 Visual Studio 中,按下 [F5] 開始偵錯。 您的網頁瀏覽器會開啟至 http://localhost:*portnum*/
,其中 portnum 是一些連接埠號碼。
將 HTTP 要求傳送至 http://localhost:*portnum*/api/admin
: 因為 Entity Framework 需要建立和植入資料庫,因此要完成第一個要求可能會較費時。 回應會顯示類似下列內容:
HTTP/1.1 200 OK
Server: ASP.NET Development Server/10.0.0.0
Date: Mon, 18 Jun 2012 04:30:33 GMT
X-AspNet-Version: 4.0.30319
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Content-Type: application/json; charset=utf-8
Content-Length: 175
Connection: Close
[{"Id":1,"Name":"Tomato Soup","Price":1.39,"ActualCost":0.99},{"Id":2,"Name":"Hammer",
"Price":16.99,"ActualCost":10.00},{"Id":3,"Name":"Yo yo","Price":6.99,"ActualCost":
2.05}]