共用方式為


第 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 檔案中的新資料庫連結字串。

[方案總管] 專案檢視的螢幕擷取畫面。AdminController 點 c s 和 OrdersContext 點 c s 會反白顯示。

開啟 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}]