デベロッパー
デベロッパー
ASP.NET 4.0におけるURLルーティング
はじめに
.NET Framework 3.5 SP1では、ASP.NETルーティングが導入され、リソースのURLをWebサーバ上の物理的なファイルから切り離すことが可能になりました。ASP.NETルーティングにより、開発者は、ルートパターンをコンテンツ生成クラスにマップするルーティングルールを定義できます。例えば、Categories/<カテゴリ名>というURLを、<カテゴリ名>を受け取ってそのカテゴリの商品一覧HTMLを生成するクラスにマップできます。このマッピングにより、ユーザーはwww.yoursite.com/Categories/BeveragesというURLを訪問することで、「Beverages(飲料)」のカテゴリにある商品を参照できるようになります。.NET 3.5 SP1では、ASP.NETルーティングは主にASP.NET MVCアプリケーション向けに設計されていました。記事「Using ASP.NET Routing Without ASP.NET MVC」で述べたように、ASP.NETルーティングをWeb Formsアプリケーションに実装することも可能です。しかし、Web FormsアプリケーションでのASP.NETルーティングの実装には、やや肉体労働的な作業が必要になります。Web Formsでは通常、ルーティングパターンを実際のASP.NETページにマップしたいと考えます。そのためには、ルートハンドラクラスを作成する必要があります。このクラスは、ルーティングURLが要求された場合に呼び出され、適切なASP.NETページへとその要求を転送します。例えば、ルート(
Categories/<カテゴリ名>など)を物理的ファイル(ShowProductsByCategory.aspxなど)にマップするには、次の3つの処理が必要になります。- Global.asaxにおいてマッピングを定義する これによって、ルートパターンをルートハンドラクラスにマップします。
- ルートハンドラクラスを作成する このクラスは、URLを解析し、ルートパラメータがあれば、それをターゲットページからアクセス可能なロケーション(
- ターゲットページのコードを記述する ルートパラメータを取得し、それに基づいてコンテンツをレンダリングするコードを記述します。
HttpContext.Itemsなど)に保存し、要求されたルートを処理するターゲットページまたはHTTPハンドラのインスタンスを返します。幸い、ASP.NET 4.0では、上述の複雑さを隠蔽することのできる、いくつかのクラスとヘルパーメソッドが追加され、Web FormアプリケーションでのASP.NETルーティングが大幅に簡素化されました。ASP.NET 4.0では、より簡単にルーティングルールを定義することができ、特別なルートハンドラクラスを作成する必要はありません。本稿では、これらの拡張点について解説したいと思います。
ASP.NET 4.0の現在のステータスとリリース予定
本稿執筆時点で、ASP.NET 4.0はベータ版が提供されています。.NET Framework 4.0とVisual Studio 2010 Beta 2をダウンロードするか、ASP.NET 4.0が正式にリリースされるまでお待ちください。現時点でASP.NET 4.0の正式版は、2010年4月にリリース予定です。
ASP.NETルーティングの概要
ASP.NETルーティングでは、URLをWebページのファイル名から完全に切り離し、簡潔で分かりやすい「SEO(検索エンジン最適化)フレンドリなURL」の作成を可能とします。WebアプリケーションでASP.NETルーティングを使用する利点については、筆者の以前の記事「Using ASP.NET Routing Without ASP.NET MVC」の「The Case for ASP.NET Routing」のセクションを参照ください。その中で数段落を割いてASP.NETルーティングの利点について詳説しています。簡単に言えば、開発者はASP.NETルーティングにより、
Categories/<カテゴリ名>といったルートパターンを、その要求を処理するクラスにマップする「ルーティングルール」を定義できます。これらのルーティングルールは、アプリケーション起動時に、Global.asaxのApplication_Startイベントハンドラにおいて定義されます。Web Formsアプリケーションでは、対象のコンテンツを生成するASP.NETページはおそらく既に存在するため、ここで必要な処理は、ルートパターンをASP.NETページにマップするルーティングルールを定義し、ルートパラメータ(<カテゴリ名>など)があればそれをそのASP.NETページに引き渡すことだけになります。ASP.NET 3.5 SP1のASP.NETルーティングでは、ルーティングパターンをASP.NETページに直接マップする方法がありませんでした。そのために、入力要求に関する情報を受け取り、要求を処理するHTTPハンドラを返す、ルートハンドラクラスを作成する必要がありました。Web Formsアプリケーションにおけるルートハンドラクラスの処理は通常、以下のステップからなります。- 必要に応じてURLを解析します。通常は、特定のルーティングパラメータを調べて、その値によって処理を決定します。
- URLの中に、この要求を処理するASP.NETページまたはHTTPハンドラへと引き渡す必要のあるルーティングパラメータがあれば、取り出します。ここでは要するに、要求されたコンテンツを実際に生成するASP.NETページが、<カテゴリ名>などのルーティングパラメータの値を参照できるようにすることが必要です。このための手段として、
HttpContext.Itemsコレクションにその情報を格納するという方法があります。HttpContext.Itemsコレクションは、要求の有効期間の間、データを保持するリポジトリの役割を果たします(Itemsコレクションの詳細については、記事「HttpContext.Items - a Per-Request Cache Store」を参照ください)。 - 処理を行うASP.NETページまたはHTTPハンドラのインスタンスを返します。
HttpContext.Itemsコレクションに格納し、このURLのコンテンツを生成するASP.NETページのインスタンスを作成して返します。お決まりの形式になることから、ルートハンドラクラスの作成は、新しいルートの1つ1つに対し、以前作成したルートハンドラクラスとほとんど同一の処理を行う新しいルートハンドラクラスをいちいち作成するという、単調な作業となります。ASP.NET 3.5 SP1のASP.NETルーティングにはもう1つ、コンテンツを生成するASP.NETページに関する問題点があります。このページは、ルーティングパラメータを、
HttpContext.Itemsコレクション(または、ルートハンドラクラスがパラメータを格納したそれ以外の場所)から読み出さなければなりません。また、ハイパーリンクやResponse.Redirectの呼び出しのために、ルーティングフレンドリなURL(Categories/<カテゴリ名>など)を生成する構文は、やや冗長で紛らわしいものになっています。ASP.NET 4.0のASP.NETルーティングでは、多様なルーティング関連のメソッドが新たに追加され、実際のASP.NETページへとマップするルーティングルールの定義がかなり簡素化されています。仲介的な役割を担うルートハンドラクラスを特別に作成する必要はなくなり、Global.asaxのルーティングルールから直接、ASP.NETページを参照できます。ルーティングルールでASP.NETページを指定すると、ルーティングパラメータが新しい
RouteDataコレクションに自動的に格納されます。ASP.NETページからは、Page.RouteDataを介してRouteDataコレクションにアクセスできます。さらに.NET Framework 4.0では、カスタムパラメータコントロールが使用できるため、ASP.NETのデータソースコントロール(SqlDataSourceやLinqDataSourceなど)から、RouteDataコレクションの中の値を、宣言して使用できます。ルーティングフレンドリなURLを生成したり、ルーティングフレンドリなURLへとリダイレクトしたりするためのメソッドも提供されています。
本稿では、ASP.NET 4.0におけるASP.NETルーティングの拡張点について説明します。本稿のダウンロード可能なデモプログラムの動作は、記事「Using ASP.NET Routing Without ASP.NET MVC」で紹介したプログラムと同じです。これはNorthwind Tradersのオンラインストアフロントとして機能するWeb Formsアプリケーションになります。ASP.NETルーティングを使用することにより、簡潔でSEOフレンドリなURLを生成します。例えば、
エンドユーザーの観点からは、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ルーティングを使用するための手順を、順を追って説明したいと思います。
Global.asaxに定義されたルートは、どのルートハンドラがどのURLパターンを処理するかを示すものです。MVCアプリケーションでは、「Controller/Action/ID」というパターンがよく使用され、
本稿のデモプログラムは、簡単なデータ駆動のアプリケーションです。Northwindデータベースを使用し、次のような、一目でその意味が分かる形式のURLを使用します。
続く2つの
/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/<商品名>:指定された商品に関する情報を表示する。
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}パラメータの値にアクセスできます。ステップ2:要求を処理するASP.NETページを作成する
ASP.NET 4.0では、特別なルートハンドラクラスを作成する必要はありません。MapPageRouteメソッドを使用すれば、その処理がすべて、裏で自動的に実行されます。従って残された作業は、要求(AllCategories.aspx、CategoryProducts.aspx、ViewProduct.aspx)を処理するASP.NETページを作成することだけです。デモプログラムのASP.NETページは、非常に簡単なものです。ルーティングパラメータによってCategoriesまたはProductsテーブルからデータベース結果を取得し、それにデータソースコントロールをプログラムによってバインドし、使用します。デモプログラムでは、データへのアクセスにLINQ-to-SQLツールを使用しています。App_Codeフォルダの中に、Northwind.dbmlというファイルがあり、そこで
NorthwindDataContextクラスを作成します。ViewProduct.aspxページには、商品名、提供企業、単位あたり数量、価格などの関連情報を表示するために定義されたフィールドを持つ、DetailsViewコントロールがあります。このページのコードビハインドクラスのコードを、以下に示します(コードは一部省略されています)。
protected void Page_Load(object sender, EventArgs e)
{
dvProductInfo.DataSource = new Product[] { Product };
dvProductInfo.DataBind();
}
private Product _Product = null;
protected Product Product
{
get
{
if (_Product == null)
{
string productName = Page.RouteData.Values["ProductName"] as string;
NorthwindDataContext DataContext = new NorthwindDataContext();
_Product = DataContext.Products.Where(p => p.ProductName == productName).SingleOrDefault();
}
return _Product;
}
}
Page_Loadイベントハンドラにおいて、DetailsViewコントロールを、Productプロパティによって返されたProductオブジェクトにバインドしています。Productプロパティは、Page.RouteData.Values["ProductName"]という構文により、Page.RouteDataコレクションからURLの中の<商品名>パラメータの値を読み出します。そして、この<商品名>パラメータの値を用いたLINQクエリによって、その特定の商品に関する情報を取得します。以下のスクリーンショットは、動作中のViewProduct.aspxページを示したものです。ページのURLは
/Products/Chaiで、ページにはチャイに関する詳細情報が表示されています(デモプログラムの他のスクリーンショットについては、記事「Using ASP.NET Routing Without ASP.NET MVC」を参照ください。この記事には、Categories/AllとCategories/<カテゴリ名>の両ページのスクリーンショットが掲載されています)。これで終わりです。ASP.NET 4.0におけるASP.NETルーティングの設定は、以上ですべて完了しました。5つの処理が必要だったASP.NET 3.5 SP1に対し、ステップ数はわずか2つと、格段に容易になっていることが分かります。
ルーティングフレンドリなURLを生成する
ハイパーリンクを作成したり、Response.Redirectによってユーザーをあるページから別のページへとリダイレクトしたりする場合には、ASP.NETページをその実際の名前で参照するよりも、Global.asaxに定義されたルーティングパターンを使用する方が理想的です。例えばViewProducts.aspxページには、Categories/<カテゴリ名>にリンクされた、その商品のカテゴリに含まれる全商品を一覧表示するページに戻るためのリンクがあります。<カテゴリ名>は、表示する商品を含むカテゴリの名前です。このようなルーティングフレンドリなURLを、Page.GetRouteUrlメソッドを用いて生成できます。このメソッドにはいくつかのオーバーロードメソッドがありますが、最も簡単なのは、ルートの名前とパラメータの値という2つの引数を持つものです。例えば、
Categories/<カテゴリ名>ページに戻るための正しいURLを取得するには、以下の構文を使用します。
Page.GetRouteUrl("View Category", new { CategoryName = <カテゴリ名> });
CategoryNameパラメータの値です。より具体的なコードを示すと、以下のようになります。
Page.GetRouteUrl("View Category", new { CategoryName = "Beverages" });
Response.Redirectの新しいバージョンである、Response.RedirectToRouteという名前のメソッドも提供されています。Page.GetRouteUrlメソッドと同様に、Response.RedirectToRouteはルート名とパラメータ値を引数とし、適切な、ルーティングフレンドリなURLへとユーザーをリダイレクトします。以下に、特定の商品を紹介するページへとユーザーをリダイレクトする方法を示します。
Response.RedirectToRoute("View Product", new { ProductName = <商品名> });
まとめ
ASP.NETルーティングは、.NET Frameworkにおける強力なライブラリです。開発者はこれを用いることで、アプリケーションで扱うURLを、実際の物理的なファイルから切り離すことができます。ASP.NET 3.5 SP1で導入されたASP.NETルーティングは当初、ASP.NET MVCアプリケーション向けに設計されていました。Web Formアプリケーションで使用することは可能でしたが、その設定には単調な作業の繰り返しが必要で、作成されるコードも、不要ではないかと感じるほど、重複の多いものでした。ASP.NET 4.0では、ASP.NETルーティングライブラリが強化され、より自由かつ直感的にWeb Formアプリケーションに使用できるようになりました。本稿で示したように、Global.asaxに数行のコードを記述するだけで、ルーティングパターンをASP.NETページにマップできます。特別なルートハンドラクラスを作成する必要はなくなりました。ASP.NETルーティングライブラリが裏で自動的に、ルーティングパラメータを、Pageクラスからアクセス可能なRouteDataコレクションに保存します。さらに、これらのRouteDataの値には、SqlDataSourceやObjectDataSourceといったデータソースコントロールから、宣言してアクセスできます。それでは、ハッピープログラミング!
参考資料
著者紹介
Scott Mitchell(Scott Mitchell)
New Topics
Special Ad
| ウマいもの情報てんこ盛り「えん食べ」 | |
![]() |
「えん食べ」は、エンジョイして食べる、エンターテイメントとして食べものを楽しむための、ニュース、コラム、レシピ、動画などを提供します。 てんこ盛りをエンジョイするのは こちらから |
Hot Topics
IT Job
今週のIT求人情報
Interviews / Specials
Follow japan.internet.com
ネット選挙
Popular
Access Ranking
Partner Sites













