ASP.NET 4.5 から導入された ASP.NET Web API を使用してみました。下記に参考にしたURLを記載しておきます。

 Learn About ASP.NET Web API
http://www.asp.net/web-api
Creating a Web API that Supports CRUD Operations
http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web-api-that-supports-crud-operations

検証環境

  • ASP.NET 4.5 Visual Studio 2012
  • Windows Server 2012

1. ソリューションの作成

下図のようにASP.NET MVC 4 Web アプリケーションプロジェクトテンプレートを使用してプロジェクトを作成します。本記事ではWebApi という名前でプロジェクトを作成したものとします。

MVC 4 プロジェクトテンプレート選択画面で Web API を選択します。 OK ボタンをクリックします。

ソリューションエクスプローラーで Controllers フォルダーを展開すると下図のように既定では ValueControllers.cs という API コントローラークラスが作成されます。今回はゼロから作成していきたいので ValuesController.cs は削除します。

2. API Controller クラスの実装

Web API 用のコントローラークラスを作成していきます。 Controllers フォルダーを右クリック→追加→コントローラー をクリックします。

下図のようなコントローラーの追加ダイアログが表示されます。コントローラー名を本例では下図のように UserControllerとしました。テンプレートに 空の API コントローラー を選択します。追加ボタンをクリックして API コントローラークラスを作成します。

Entity Framework を使用する場合は、 テンプレートで Entity Framework を使用した、読み取り/書き込み操作のある API コントローラーを選択してAPIコントローラーのひな形を作成することもできます。

今回は次のようなAPIコントローラークラスを作成してみました。TestUserは適当に作成したモデルクラスになります。Web API は メソッドの名前規約により、GETで始まるメソッドは HTTPの GET メソッドに対応します。同じように PUT, POST, DELETE で始まるメソッドはHTTPの PUT, POST, DELETE リクエストにマップされます。引数のない GetXXX メソッドが /api/user/ のように id の指定なしで呼び出されたときに使用されるメソッドになります。そのため、 /api/user/ のようなパスでリクエストされた場合、GetUsers メソッドが呼び出されるようになります。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebApi.Models;

namespace WebApi.Controllers
{
    /// <summary>
    /// WebApiのユーザーコントローラ
    /// WebApiの使い方は http://www.asp.net/web-api が参考になります。
    /// WebApiコントローラーの作り方は以下のURLなどのチュートリアルが参考になります。
    /// http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web-api-that-supports-crud-operations
    /// </summary>
    public class UserController : ApiController
    {
        private IList<TestUser> Users = TestUser.GenerateDemoUsers();
        /// <summary>
        /// パラメータのない GET メソッドに対応するメソッド 
        /// 例:GET /api/user/
        /// </summary>
        /// <returns></returns>
        public IEnumerable<TestUser> GetUsers()
        {
            return Users;
        }

        /// <summary>
        /// id パラメータのある GETメソッドに対応するメソッド
        /// 例:/api/user/1
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public TestUser GetUser(int id)
        {
            TestUser u = Users.FirstOrDefault(x => x.ID == id);
            if (u == null)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
            }
            return u;
        }

        /// <summary>
        /// name パラメータのある GETメソッドに対応するメソッド
        /// 例:GET /user/?name=Test
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public TestUser GetUserByName(string name)
        {
            TestUser u = Users.FirstOrDefault(x => x.Name.StartsWith(name, StringComparison.InvariantCultureIgnoreCase));
            if (u == null)
            {
                throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
            }
            return u;
        }

        /// <summary>
        /// POSTメソッドに対応するメソッド。モデルを作成します。
        /// 例:POST /api/user/
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public HttpResponseMessage PostProduct(TestUser user)
        {
            if (ModelState.IsValid)
            {
                user.ID = this.Users.Max(x => x.ID) + 1;
                this.Users.Add(user);
                HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created);
                response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = user.ID }));
                return response;
            }
            return Request.CreateResponse(HttpStatusCode.BadRequest);
        }

        /// <summary>
        /// PUTメソッドに対応するメソッド。モデルを更新します。
        /// 例:PUT /api/user/1
        /// </summary>
        /// <param name="id"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public HttpResponseMessage PutUser(int id, TestUser user)
        {
            if (ModelState.IsValid && id == user.ID)
            {
                // update
            }
            else
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            }


            return Request.CreateResponse(HttpStatusCode.OK);
        }


        /// <summary>
        /// DELETEメソッドに対応するメソッド。モデルを削除します。
        /// DELETE /api/user/1
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public HttpResponseMessage DeleteUser(int id)
        {
            TestUser u = Users.FirstOrDefault(x => x.ID == id);
            if (u == null)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }

            // Remove 処理
            return Request.CreateResponse(HttpStatusCode.OK, u);

        }
    }
}

参考までにTestUserモデルクラスのソースも記載しておきます。

 

変更を保存しビルドを行ってエラーが発生しないことを確認してください。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApi.Models
{
    public class TestUser
    {
        public int ID { get; set; }

        public string Name { get; set; }

        public string Email { get; set; }

        public string Telephone { get; set; }

        public static IList<TestUser> GenerateDemoUsers()
        {
            List<TestUser> users = new List<TestUser>();
            users.Add(new TestUser
            {
                ID = 1,
                Name = "Test Taro",
                Email = "test.taro@sample.jp",
                Telephone = "08111222333"
            });
            users.Add(new TestUser
            {
                ID = 2,
                Name = "Test Hanako",
                Email = "test.hanako@sample.jp",
                Telephone = "08111222334"
            });
            users.Add(new TestUser
            {
                ID = 3,
                Name = "Nihon Ichiro",
                Email = "nihon.ichiro@sample.jp",
                Telephone = "08111222335"
            });
            users.Add(new TestUser
            {
                ID = 4,
                Name = "Nihon Hanako",
                Email = "nihon.hanako@sample.jp",
                Telephone = "08111222336"
            });

            return users;
        }
    }   
}

/api/<コントローラー>/ とぃうパスへのリクエストが発生したときに Web API 用のコントローラーに処理がルーティングされるのは、以下のように /api/コントローラー/id というWebApi用のルーティングの設定が Global.asax から呼び出されるApp_Start/WebApiConfig.cs で設定されているためです。

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

2.動作確認

F5キーを入力してプロジェクトをデバッグ実行します。起動したブラウザーで下図のように /api/user/ というパスを入力してEnterキーを入力します。

UserController の 引数のない GetUsers メソッドが呼び出され TestUser の一覧がjson形式でダウンロードされます。

実際にファイルの中身を確認すると 下図のように JSON形式の文字列になっていることが確認できます。

下図のように name=Test というクエリパラメーターをしていすると name というパラメーターに一致するシグネチャをもつ GetUserByName というメソッドが呼び出さるようになります。このとき nameという名前の引数に Test という文字列がApiController により自動的に 割り当てられます。

3.まとめ

説明は以上です。Web API を使用すると サーバーと連携する AJAX アプリケーションを簡単に作成できるようになることがわかります。