ASP.NETのURLルーティングを使用する / ASP.NETでのURLの書き換え mod_rewriteを実現する

ASP.NETのURLルーティングを実装する手順を紹介します。

プロジェクトの作成

Visual Studioを起動し、ASP.NET のプロジェクトを作成します。今回は[ASP.NET Web アプリケーション (.NET Framework)]を作成します。


URLルーティング部分をシンプルに実装するため、今回はプロジェクトの種類は[空]を選択します。


プロジェクトが作成できました。

Global.asax グローバルアプリケーションクラスの追加

空のプロジェクトに、グローバルアプリケーションクラスを追加します。
ソリューションエクスプローラでプロジェクトのノードをクリックして選択します。右クリックしてポップアップメニューを表示し、[追加]メニュー内の[新しい項目]をクリックします。


[新しい項目の追加]ダイアログボックスが表示されます。左側のツリービューで[Web]のノードを選択します。右側の追加する項目のリストから[グローバル アプリケーション クラス]をクリックして選択します。ファイル名はデフォルトの"Global.asax"とします。


Global.asax ファイルが追加されました。

Webフォームの追加

続いてWebフォームを追加します。先ほどと同様の手順で[新しい項目の追加]ダイアログボックスを表示します。左側のツリービューで[Web]のノードを選択します。右側の追加する項目のリストから[Web フォーム]をクリックして選択します。ファイル名は"Default.aspx"とします。


Webフォームが作成され、追加されます。Webフォームのデザイン画面を開き、ツールボックスからLabelコントロールをWebフォームにドラッグ&ドロップし、WebフォームにLabelコントロールを配置します。

Global.asax の実装

System.Web.Routing の追加

ソリューションエクスプローラで、Global.asaxの項目をダブルクリックします。Global.asax.csファイルの編集画面が表示されます。

コードエディタで、Global.asax.csファイルの先頭にSystem.Web.Routingを読み出すusingを追加します。
using System.Web.Routing;

MapPageRouteの処理の実装

続いて、Global.asax.csファイルに、RegisterRoutesメソッド(この名前は任意の名前でよいです。)を追加します。
下記のコードを記述します。
void RegisterRoutes(RouteCollection routes)
{
  routes.MapPageRoute("","{productid}", "~/Default.aspx");
}
また、RegisterRoutesを呼び出す処理を Application_Start メソッド内に記述します。
void Application_Start(object sender, EventArgs e)
{
  RegisterRoutes(RouteTable.Routes);
}
補足
処理が単純であれば、Application_Start内にMapPageRouteを記述しても問題ありません。今回の例では、URLルーティングが増えMapPageRouteの数が増えることを想定して、別メソッドに分けてあります。
void Application_Start(object sender, EventArgs e)
{
  RouteTable.Routes.MapPageRoute("","{productid}", "~/Default.aspx");
}

解説

下記のコードにより、アプリケーションのルートURLの直後に記述された文字列を"productid"パラメーターとして、Default.aspxにURLを書き換えます。
  routes.MapPageRoute("","{productid}", "~/Default.aspx");
http://(アプリケーションのルートURL)/PenguinCookie
のURLは
http://(アプリケーションのルートURL)/Default.aspx
のページが実際には表示されます。このとき、Page.RouteData の productid パラメーターに "PenguinCookie"が渡される動作になります。
Global.asax.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Web.Routing;

namespace AspNetRouting
{
  public class Global : System.Web.HttpApplication
  {

    protected void Application_Start(object sender, EventArgs e)
    {
      RegisterRoutes(RouteTable.Routes);

    }

    protected void Session_Start(object sender, EventArgs e)
    {

    }

    protected void Application_BeginRequest(object sender, EventArgs e)
    {

    }

    protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {

    }

    protected void Application_Error(object sender, EventArgs e)
    {

    }

    protected void Session_End(object sender, EventArgs e)
    {

    }

    protected void Application_End(object sender, EventArgs e)
    {

    }

    void RegisterRoutes(RouteCollection routes)
    {
      routes.MapPageRoute("", "{productid}", "~/Default.aspx");
    }
  }
}

Webフォームの実装

WebフォームのPage_Loadイベントに下記コードを記述します。
Default.aspx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace AspNetRouting
{
  public partial class Default : System.Web.UI.Page
  {
    protected void Page_Load(object sender, EventArgs e)
    {
      Label1.Text = (string)Page.RouteData.Values["productid"];
    }
  }
}

解説

URLルーティングによってページが表示された際に、Page.RouteData オブジェクトにアクセスしてURLルーチンぐされる前の元のURLのパラメーターを取得します。パラメーターの値を取得するには、Valuesメソッドを呼び出します。Valuesメソッドの第一引数にパラメーター名を与えます。今回の例では、アプリケーションのルートURL以降の文字列を"productid"パラメータとして設定しているため、パラメーター名の"productid"を与えています。

実行結果

プロジェクトを実行します。Default.aspxが表示された状態が下図となります。


http://(アプリケーションのルートURL)/PenguinCookie
をURLに入力して開きます。Default.aspxのページが表示され、LabelにURLパラメーターの"PenguinCookie"が表示されていることが確認できます。実際はDefault.aspxが開かれていますが、URLのボックスには入力したURLがそのまま表示されており、リダイレクトなどはされていないことも確認できます。

パラメータを複数にする

RegisterRoutesメソッド内で、下記のように複数のパラメータを設定可能です。
routes.MapPageRoute("","log/{year}/{category}", "~/Default.aspx");
この場合以下のURLを入力した場合
http://(アプリケーションのルートURL)/log/2009/error
Default.aspxページにルーティングされ Page.RouteData.Values の値は以下になります。
Page.RouteData.Values["year"]="2009"
Page.RouteData.Values["category"]="error"

デフォルト値と制約

ルーティングされるURLのデフォルト値や制約をつけることもできます。
下記の例ではパラメータ部を省略すると locale=US,year=(今年)となります。また、localeはaからzまでの2文字、yearは数値4桁の制約となります。
routes.MapPageRoute("Route001", "Report/{locale}/{year}/{*extrainfo}", "~/viewreport.aspx", true,
    new RouteValueDictionary { 
        { "locale", "US" }, 
        { "year", DateTime.Now.Year.ToString() } },
    new RouteValueDictionary { 
        { "locale", "[a-z]{2}" }, 
        { "year", @"\d{4}" } });





以前のサンプル

以前のサンプルは下記になります。

実装

プロジェクトの新規作成で、[ASP.NET Webアプリケーション]プロジェクトを作成します。


ソリューション内に下記のファイルが作成されます。


Global.asax.csファイルを開きます。

先頭にSystem.Web.Routingを読み出すusingを追加します。
using System.Web.Routing;
を記述します。


Session_Endメソッドの下に RegisterRoutesメソッド(この名前は任意の名前でよいです。)を追加します。
void RegisterRoutes(RouteCollection routes)
{
}
を記述します。
RouteCollectionクラスを参照するためにSystem.Web.Routingが必要です。


Application_Startメソッドから RegisterRoutesメソッドを呼び出すコードを記述します。
void Application_Start(object sender, EventArgs e)
{
  RegisterRoutes(RouteTable.Routes);
}
とします。


RegisterRoutesメソッドを実装します。
void RegisterRoutes(RouteCollection routes)
{
  routes.MapPageRoute("","products/{productid}", "~/Default.aspx");
}
とします。


Default.aspxを開きます。ようこそ画面が自動生成されています。


自動生成されているコードを削除し、Labelコントロールを配置します。


Default.aspx.csを開きPage_Loadメソッドに以下のコードを記述します。
public void Page_Load(object sender, EventArgs e)
{
  Label1.Text = (string)Page.RouteData.Values["productid"];
}
とします。


実行結果

アプリケーションを実行します。Default.aspxの画面をブラウザで表示してみます。下図の画面が表示されます。


URLを
http://(サーバーのURL)/products/542
としてみます。


542が画面に表示されました。

説明

RegiterRoutesメソッド内の
routes.MapPageRoute("","products/{productid}", "~/Default.aspx");
により、ルーティングを追加できます。上記の書式では
http://(アプリケーションのルートURL)/products/(任意の文字)
のURLはすべて
http://(アプリケーションのルートURL)/Default.aspx
にルーティングされます。
"{}"でくくられた部分がパラメータ扱いとなります。パラメータはPage.RouteData.Valuesに格納されルーティング先のページで参照できます。今回は/products/以下をパラメータとして扱う記述にしましたので
http://(アプリケーションのルートURL)/products/542
とURLを入力した場合には、「542」の部分がPage.RouteData.Values["products"]に設定されます。

補足

空のWebアプリケーションサイトを作成した場合は、Global.asaxファイルはありませんので、ソリューションエクスプローラ等で[項目の追加]を選択し[グローバル アプリケーション クラス]を選択するとGlobal.asaxファイルを追加できます。



著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2010-05-15
iPentec all rights reserverd.