本稿では、ASP.NET 4.0におけるASP.NETルーティングの拡張点について説明します。本稿のダウンロード可能なデモプログラムの動作は、記事「Using ASP.NET Routing Without ASP.NET MVC」で紹介したプログラムと同じです。これはNorthwind Tradersのオンラインストアフロントとして機能するWeb Formsアプリケーションになります。ASP.NETルーティングを使用することにより、簡潔でSEOフレンドリなURLを生成します。例えば、/Categories/Allは全カテゴリを表示し、/Categories/Beveragesは「飲料」カテゴリ内の全商品を一覧表示し、/Products/Chaiは商品「チャイ」に関する情報を表示します。記事「Using ASP.NET Routing Without ASP.NET MVC」のデモプログラムは、ASP.NET 3.5 SP1のASP.NETルーティングの使用方法を示すものでした。本稿のデモプログラムでは、ASP.NET 4.0のASP.NETルーティングを使用しています。
エンドユーザーの観点からは、2つのプログラムは機能も形式もまったく同じです。両者の違いは、ASP.NETルーティングを使用するためのWebサイトの設定に必要な処理と、Global.asaxで使用する構文、そしてコードビハインドページです。例えば、ASP.NET 3.5 SP1のASP.NETルーティングでは、プロジェクトにSystem.Web.Routingアセンブリを明示的に追加し、Web.configにマークアップを追加する必要がありました。ASP.NET 4.0では、このような処理は不要になりました。ASP.NET 4.0では、Global.asaxでルーティングルールを定義するために使用する構文と、コードビハインドページのコードも、短く、シンプルで、分かりやすいものになっています。
以下では、ASP.NET 4.0のASP.NETルーティングを使用するための手順を、順を追って説明したいと思います。
ステップ0:前提条件
このデモプログラムでは、ASP.NET 4.0に追加されたASP.NETルーティングの機能を使用します。従って、Visual Studio 2010か、Visual Web Developer 2010(またはそれ以降)の使用が必要になります。
ステップ1:Global.asaxにおいて、ルーティングルールを定義する
ASP.NETルーティングを使用するには、アプリケーションの起動時に1つ以上のルートを定義しなければなりません。まず、プロジェクトにGlobal Application Classファイルタイプ(Global.asax)を追加します。Application_Startイベントにおいて、これにルートを登録します。
Global.asaxに定義されたルートは、どのルートハンドラがどのURLパターンを処理するかを示すものです。MVCアプリケーションでは、「Controller/Action/ID」というパターンがよく使用され、/Products/View/Aniseed SyrupやCategories/Edit/Beveragesといった形式の要求が、設定されたルートハンドラによって処理されます。アプリケーションにおけるルートを、かなり自由に定義できます。複数の部分からなるパターンを定義したり、指定されなかった部分に代入するデフォルト値を定義したり、特定の種類の入力の一部に対し、制約を設けたりすることもできます。
本稿のデモプログラムは、簡単なデータ駆動のアプリケーションです。Northwindデータベースを使用し、次のような、一目でその意味が分かる形式のURLを使用します。
/Categories/All:データベースの全カテゴリを一覧表示する。/Categories/<カテゴリ名>:指定されたカテゴリの全商品を一覧表示する。/Products/<商品名>:指定された商品に関する情報を表示する。
そこで、以下のコードに示すように、Global.asaxファイルの中のApplication_Startイベントハンドラに3つのルートを定義しました。
RouteTableオブジェクトとRouteCollectionクラスは、System.Web.Routing名前空間に存在するため、この名前空間をインポートするか、System.Web.Routing.RouteTableというように、完全修飾クラス名を使用する必要があります。
void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}
void RegisterRoutes(RouteCollection routes)
{
// Register a route for Categories/All
routes.MapPageRoute(
"All Categories", // Route name
"Categories/All", // Route URL
"~/AllCategories.aspx" // Web page to handle route
);
// Route to handle Categories/{CategoryName}.
// The {*CategoryName} instructs the route to match all content after the first slash, which is needed b/c some category names contain a slash, as in the category "Meat/Produce"
// See http://forums.asp.net/p/1417546/3131024.aspx for more information
routes.MapPageRoute(
"View Category", // Route name
"Categories/{*CategoryName}", // Route URL
"~/CategoryProducts.aspx" // Web page to handle route
);
// Register a route for Products/{ProductName}
routes.MapPageRoute(
"View Product", // Route name
"Products/{ProductName}", // Route URL
"~/ViewProduct.aspx" // Web page to handle route
);
}
Application_Startでは、RouteCollectionであるRouteTable.Routesを引数として、RegisterRoutesメソッド(そのすぐ下で定義されています)を呼び出します。RegisterRoutesメソッドでは、RouteCollectionクラスのMapPageRouteを呼び出します。MapPageRouteでは、ルーティングパターンとASP.NETページの間のルートマッピングを定義します。例えば、MapPageRouteの最初の呼び出しでは、Categories/Allというルートパターンを~/AllCategories.aspxというASP.NETページにマップする、「All Categories」という名前のルートを作成しています。
続く2つのMapPageRouteに対する呼び出しでは、パラメータを持つルーティングパターンを作成しています。ルート「View Product」は、Products/{ProductName}というパターンを~/ViewProduct.aspxというASP.NETページにマップします。{ProductName}はパラメータであり、Products/<商品名>という形式のすべての要求が~/ViewProduct.aspxに引き渡されることを表します。すぐ後で説明しますが、~/ViewProduct.aspxからは、Page.RouteDataパラメータを介して、{ProductName}パラメータの値にアクセスできます。
