はじめに
.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ハンドラのインスタンスを返します。
ルートパラメータを取得し、それに基づいてコンテンツをレンダリングするコードを記述します。
以上、読むだけでも大変だったでしょうから(書いた筆者も疲れました)、Web FormsアプリケーションでのASP.NETルーティングの実装が必ずしも単純明快な作業ではないことがお分かりいただけたと思います。
幸い、ASP.NET 4.0では、上述の複雑さを隠蔽することのできる、いくつかのクラスとヘルパーメソッドが追加され、Web FormアプリケーションでのASP.NETルーティングが大幅に簡素化されました。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へとリダイレクトしたりするためのメソッドも提供されています。