ASP.NET Web API を使ってみよう: MVC 4 新機能シリーズ


ASP.NET MVC 4 Beta では、ASP.NET Web API という新しいフレームワークが追加されました。この ASP.NET Web API (以後 Web API と記します) は、ブラウザーやモバイルデバイスを含むさまざまなクライアントに対して RESTful なサービスを提供するのに適した HTTP サービス構築用のフレームワークです。まずは以下に ASP.NET MVC 4 Beta リリース ノートASP.NET Web API 項目の簡約を記載します。

  • 最新の HTTP プログラミングモデル
    Web API では、新しい強く型付けされた HTTP オブジェクトモデルを使って HTTP リクエストとレスポンスを直接操作できます。
  • ルーティングのフルサポート
    Web API は、ルートパラメーターや制約などの URL ルーティングの全機能をサポートします。加えて、規約によるアクションへのマッピングをサポートします。したがって、[HttpPost] などの属性をクラスやメソッドに付加する必要がありません。
  • Content negotiation
    クライアントとサーバーは、API から返されるデータの最適なフォーマットを決定して協調動作します。デフォルトでは、XML, JSON, Form URL encoded formats をサポートし、カスタムフォーマッタ―を追加して拡張も可能です。また、デフォルトの Content negotiation strategy を置き換えることさえ可能です。
  • モデルバインディングと検証
    モデルバインダーは HTTP リクエストのメッセージデータを Web API アクションで使われる .NET オブジェクトに簡単にバインドすることができます。
  • アクションフィルター
    Web API は [Authorize] 属性などのアクションフィルターをサポートします。また、カスタムアクションフィルターも作成して使用することができます。
  • Query composition
    Web API は、IQueryable<T> を返すことで簡単に OData の URL 規約によるクエリーをサポートできます。
  • Improved testability of HTTP details
    Web API アクションは HttpRequestMessage と HttpResponseMessage のインスタンスと共に動作します。また、これらのオブジェクトのジェネリック版を使うことで、HTTP タイプにカスタムタイプを追加することもできます。
  • Improved Inversion of Control (IoC) via DependencyResolver
    Web API は MVC の dependency resolver で用いられる Service locator pattern を使います。
  • Code-based configuration
    Web API の設定はコードでのみ行います。config ファイルは用いません。
  • Self-host
    Web API はルーティングやその他の Web API の機能を使いながら、IIS に加えて独自プロセスでもホストさせることができます。

 

ASP.NET Web API を使った HTTP サービスの作成

それではここで、ASP.NET Web API を使ってシンプルな HTTP サービスを作成してみます。

1. 新しい Web API プロジェクトの作成

Visual Studio 2010 のメニュー [新しいプロジェクト] で “ASP.NET MVC 4 Web Application” を選び、プロジェクト名を入力します。今回も こちらのブログ記事 "Web API を始めてみよう" に合わせて “SuperHero2” としてプロジェクトを作成しました。

NewProject

続いて表示される [New ASP.NET MVC 4 Project] ダイアログで、”Web API” を選択します。

SelectWebAPI

プロジェクトが作成されると、Web API 用のコントローラー ValuesController.cs がデフォルトで生成されます。この ValuesController では、GET, POST, PUT, DELETE に対応したアクションメソッドが用意されていると共に、ApiController クラスの派生クラスとなっていることが分かります。通常の ASP.NET MVC のコントローラーでは Controller クラスからの派生クラスとなりますので、まずはここが大きく異なるところになります (下記コード参照) 。

   1: namespace SuperHero2.Controllers
   2: {
   3:     public class ValuesController : ApiController
   4:     {
   5:         // GET /api/values
   6:         public IEnumerable<string> Get()
   7:         {
   8:             return new string[] { "value1", "value2" };
   9:         }
  10:  
  11:         // GET /api/values/5
  12:         public string Get(int id)
  13:         {
  14:             return "value";
  15:         }
  16:  
  17:         // POST /api/values
  18:         public void Post(string value)
  19:         {
  20:         }
  21:  
  22:         // PUT /api/values/5
  23:         public void Put(int id, string value)
  24:         {
  25:         }
  26:  
  27:         // DELETE /api/values/5
  28:         public void Delete(int id)
  29:         {
  30:         }
  31:     }
  32: }



2. モデルの追加

続いて、API を通して提供するデータを表した POCO (Plain-old CLR Object) クラスを作ります。このクラスのオブジェクトがモデルとして、Web API で JSON や XML などのフォーマットにシリアライズされクライアントサイドに提供されるデータとなります。

ソリューションエクスプローラーの Models フォルダー上で右クリックして、[追加] - [クラス] から Hero.cs を作り、下記のコードを記述します。

AddModel 

   1: namespace SuperHero2.Models
   2: {
   3:     public class Hero
   4:     {
   5:         public int Id { get; set; }
   6:         public string Name { get; set; }
   7:     }
   8: }



3. コントローラ Get アクションの実装

ここで、デフォルトで生成された ValuesController.cs の名前をモデル名に合わせて HeroesController.cs にリネームしておきます。「ファイルの名前を変更しようとしています。このプロジェクトのコード要素 ‘ValuesController’ への参照をすべて変更しますか?」のメッセージボックスが表示されたら [はい] をクリックします。ファイル名を変更するだけで、コード内のクラス名も HeroesController に変更されます。

Rename2

   1: namespace SuperHero2.Controllers
   2: {
   3:     public class HeroesController : ApiController
   4:     {
   5:         ...
   6:     }
   7: }

続いて、HeroesController.cs に下記の参照を追加します。

   1: using SuperHero2.Models;

そして、1 つ目の Get アクション メソッドを下記に書き換えます。

   1: // GET /api/values
   2: public IEnumerable<Hero> Get()
   3: {
   4:     var heroes = new List<Hero>
   5:     {
   6:         new Hero {Id = 1, Name = "スーパーマン"},
   7:         new Hero {Id = 2, Name = "バットマン"},
   8:         new Hero {Id = 3, Name = "ウェブマトリクスマン"},
   9:         new Hero {Id = 4, Name = "チャッカマン"},
  10:         new Hero {Id = 5, Name = "スライムマン"}
  11:     };
  12:  
  13:     return heroes;
  14: }

ここでは、実装サンプルをシンプルにするために、Get アクション メソッド内にデータをハードコーディングしていますが、実際はここで何かしらのデータ アクセスをおこなってモデルデータを取得することになるでしょう。


4. 実行

ひとまずは、これで Hero モデルのリストデータを取得する Web API が実装できましたので、実行してデータが取得できるか確認してみます。F5 または Ctrl + F5 で実行すると、Web API プロジェクトテンプレートで作成された ASP.NET MVC の Index ページが表示されます。

startPage

こちらのブログ記事で紹介した WCF Web API 拡張パッケージで提供されていたようなテスト用クライアントは、現状 ASP.NET Web API では使用できませんので、ここでは IE9 の F12 開発者ツール のネットワークキャプチャ機能を使って Web API からのレスポンスデータを確認します。(Fiddler などの HTTP キャプチャツールを使用してもかまいません)

IE9 で F12 キーを押して F12 開発者ツールを開き、[ネットワーク] タブを開きます。そして、[キャプチャの開始] ボタンを押して、HTTP のキャプチャを開始します。この状態で、IE9 のアドレスバーに http://localhost:XXXX/api/heroes と入力して、リクエストとレスポンスをキャプチャします(XXXX にはスタートページのポート番号を入力します)。

F12_capture1

キャプチャ データをダブルクリックするか、選択してから [詳細ビューに移動] をクリックすると、リクエスト ヘッダーやレスポンス ヘッダーなどを確認することができます。ここで [応答本文] を見ると JSON 形式で Hero データが取得出来ていることが確認できます。

F12_capture2


5. jQuery による JSON データの取得と表示

最後に、Index.cshtml で、api/heroes から JSON 形式でヒーロー データを取得し、ページ上に表示してみます。Index.cshtml ページを開き、<div id=”body”> 内部の要素を全て削除してから、下記のスクリプトやマークアップを記述します。

   1: <!DOCTYPE html>
   2: <html lang="en">
   3: <head>
   4:     <meta charset="utf-8" />
   5:     <title>ASP.NET Web API</title>
   6:     <link href="@Url.Content("~/Content/Site.css")" 
   7:         rel="stylesheet" type="text/css" />
   8:     <script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")" 
   9:         type="text/javascript"></script>
  10:     <meta name="viewport" content="width=device-width" />
  11:  
  12:     <style type="text/css">
  13:         #heroes
  14:         {
  15:             font-family: Meiryo;
  16:             font-size: 1.2em;
  17:         }
  18:     </style>
  19:  
  20:     <script type="text/javascript">
  21:         $(function () {
  22:             // Send an AJAX request
  23:             $.getJSON("api/heroes/",
  24:                 function (data) {
  25:                     // On success, 'data' contains a list of products.
  26:                     $.each(data, function (key, val) {
  27:                         // Format the text to display.
  28:                         var str = val.Id + ': ' + val.Name;
  29:                         // Add a list item for the product.
  30:                         $('<li/>', { html: str }).appendTo($('#heroes'));
  31:                     });
  32:                 });
  33:         });
  34:     </script>
  35:  
  36: </head>
  37: <body>
  38:     <header>
  39:         <div class="content-wrapper">
  40:             <div class="float-left">
  41:                 <p class="site-title">
  42:                     <a href="/">ASP.NET Web API</a></p>
  43:             </div>
  44:         </div>
  45:     </header>
  46:     <div id="body">
  47:         <ul id="heroes"></ul>
  48:     </div>
  49: </body>
  50: </html>

jQuery は、もともとプロジェクトに追加されているバージョン 1.6.2 をそのまま使用していますが、NuGet を通して最新版にアップデートしても構いません。Web API の呼び出しには、jQuery の getJSON メソッドを利用して非同期にデータを取得し、<ul id=”heroes”> の子要素として追加しています。

実行結果は下記の通りです。Web API として用意した api/heroes から取得した JSON データが Index.cshtml ページに表示されていることが確認できます。

image


おわりに

ASP.NET MVC 4 Beta で追加された新しいフレームワーク ASP.NET Web API の概要をご紹介しました。より詳しい情報は下記の ASP.NET オフィシャルページ (英語) をご参照いただければと思います。また随時、こちらのブログなどでも機能紹介していきたいと思います。

Getting Started with ASP.NET Web API

(赤シャツ男こと ScottGu’s Blog でも ASP.NET Web API シリーズ が始まりました!)

Skip to main content