次の方法で共有


パート 3: Admin コントローラーの作成

作成者: Rick Anderson

完成したプロジェクトをダウンロードする

Admin コントローラーを追加する

このセクションでは、製品に対する CRUD (作成、読み取り、更新、削除) 操作をサポートする Web API コントローラーを追加します。 コントローラーは Entity Framework を使用してデータベース レイヤーと通信します。 管理者のみがこのコントローラーを使用できます。 顧客は別のコントローラーを介して製品にアクセスします。

ソリューション エクスプローラーで、[コントローラー] フォルダーを右クリックします。 [追加] を選択し、[コントローラー] を選択します。

Screenshot of the Solutions Explorer controllers menu. The add option is selected and Controller is highlighted.

[コントローラーの追加] ダイアログで、コントローラーの名前を AdminController にします。 [テンプレート] で、[Entity Framework を使用した、読み取り/書き込み操作のある API コントローラー] を選択します。 [モデル クラス]で、[製品 (ProductStore.Models)] を選択します。 [データ コンテキスト] で、<[新しいデータ コンテキスト]> を選択します。

Screenshot of the Add Controller dialogue box. The data context class menu is open and new data context is highlighted.

Note

[モデル クラス] ドロップダウンにモデル クラスが表示されない場合は、プロジェクトをコンパイルしたことを確認します。 Entity Framework ではリフレクションが使用されるため、コンパイル済みアセンブリが必要です。

<[新しいデータ コンテキスト]> を選択すると、[新しいデータ コンテキスト] ダイアログが開きます。 データ コンテキストの名前を ProductStore.Models.OrdersContext にします。

Screenshot of the new data context dialog. A textbox shows the name of the new data context typed in.

[OK] をクリックして、[新しいデータ コンテキスト] ダイアログを閉じます。 [コントローラーの追加] ダイアログ ボックスで、[追加] をクリックします。

次のものがプロジェクトに追加されます。

  • DbContext から派生する OrdersContext という名前のクラス。 このクラスは、POCO モデルとデータベースの間の接着剤を提供します。
  • AdminController という名前の Web API コントローラー。 このコントローラーは、Product インスタンスに対する CRUD 操作をサポートします。 OrdersContext クラスを使用して Entity Framework と通信します。
  • Web.config ファイル内の新しいデータベース接続文字列。

Screenshot of the Solutions Explorer project view. AdminController dot c s and OrdersContext dot c s are highlighted.

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 機能を実装する 5 つのメソッドを定義します。 各メソッドは、クライアントが呼び出すことができる URI に対応します。

コントローラー メソッド 説明 URI HTTP メソッド
GetProducts すべての製品を取得します。 api/products GET
GetProduct ID で製品を探します。 api/products/id GET
PutProduct 製品を更新します。 api/products/id PUT
PostProduct 新しい製品を作成します。 api/products 投稿
DeleteProduct 製品を削除します。 api/products/id DELETE

各メソッドは、OrdersContext を呼び出して、データベースに対してクエリを実行します。 コレクションを変更するメソッド (PUT、POST、DELETE) は、db.SaveChanges を呼び出してデータベースに対する変更を保持します。 コントローラーは HTTP 要求ごとに作成され、その後破棄されるため、メソッドが返される前に変更を保持する必要があります。

データベース初期化子を追加する

Entity Framework には、起動時にデータベースに入力し、モデルが変更されるたびにデータベースを自動的に再作成できる優れた機能があります。 この機能は、モデルを変更した場合でも常にいくつかのテスト データがあるため、開発中に役立ちます。

ソリューション エクスプローラーで、Models フォルダーを右クリックし、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 でデータベースが作成 (または再作成) されると、Seed メソッドが呼び出されてテーブルが入力されます。 Seed メソッドは、いくつかの製品例と 1 つの注文例を追加するのに使用します。

この機能はテストには適していますが、誰かがモデル クラスを変更するとデータが失われる可能性があるため、運用環境では DropCreateDatabaseIfModelChanges クラスを使用しないでください。

次に、Global.asax を開き、次のコードを Application_Start メソッドに追加します。

System.Data.Entity.Database.SetInitializer(
    new ProductStore.Models.OrdersContextInitializer());

コントローラーに要求を送信する

この時点ではクライアント コードを記述していませんが、Web ブラウザーまたは Fiddler などの HTTP デバッグ ツールを使用して、Web API を呼び出すことができます。 Visual Studio で F5 キーを押してデバッグを開始します。 Web ブラウザーで http://localhost:*portnum*/ が開きます。ここで、portnum はポート番号です。

"http://localhost:*portnum*/api/admin" にHTTP 要求を送信します。 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}]