ASP.NETで、URLルーティングを導入する方法をまとめたいと思います。
URLルーティングは、ASP.NET 3.5からサポートされた機能ですが、クエリなどを含む動的なURLを、静的なURLにマップする機能です。
Googleなどの検索エンジンのクローラは、クエリを含むURLに対して冷たい(内容が変化するとして検索インデックスを下げるか、スキップする)ので、静的なURLに見せかけて検索インデックスを向上させよう、というのがそもそもの狙いです。
また、クエリを含むURLはあまりフレンドリーではないので、フレンドリーなものに見せかけるというのもありますね。
例えば、www.example.com/index.aspx?a=tako&b=namakoというURLはフレンドリーではなく、また検索エンジンからも冷たくあしらわれるので、www.example.com/tako/namako/のようなURLにマップしてやれば、フレンドリーになって検索エンジンからも覚えよく扱われる、という次第です。
普通はこのように使うのですが、私の場合はプログラミングの手間を低減するために導入しました。
例えば、「新館」の「森と公園めぐり」のページでは、こんなURLで各公園のページにアクセスします。
www.naosan.jp/park/shikinomori.aspx
単純に考えれば、shikinomori.aspxというASP.NETページを作成して、ということになるのですが、公園のページはたくさんあり、それぞれにページを作っていてはたいへんです。デザインの統一もたいへんです。
そこで、park.ascxというユーザコントロールを作成し、それをshikiomori.aspxに組み込みます。共通機能はpark.ascxに実装し、park.ascxでは自らの組み込まれたページのURLを判断し、同名のテキストファイル(たとえばshikinomori.txt)を読み込み、ページごとに異なった振る舞いをさせる、というよくある方法を採用しています。
もちろん、テキストファイルを用いているのはデータが軽くプログラミングが単純だからで、データ量が大きいか複雑な場合はXMLやRDBを使うのがベターです。
この方法の面倒くささは、中身のまったく同じ.aspxファイルを公園ページごとに作らなければならない点です。面倒というか、美しくないですね。メンテナンス的にも問題がありそうです。
そこで、URLルーティングを用い、リクエストを受け付けるURLをwww.naosan.jp/park/default.aspxに一本化します。そして、公園の名前をクエリで受け取ることにします。
www.naosan.jp/park/default.aspx?place=shikinomori
これを、以下のURLになるようにglobal.asaxの Application_Startメソッド内に、マッピングルールを書き加えます(コードはC#です)。
RouteTable.Routes.MapPageRoute(
"parkRouting", //ルーティング名
"park/{place}.aspx", //ルーティング元のURL定義。{}内はパラメータ
"~/park/default.aspx"); //ルーティング先のURL
あ、System.Web.Routing名前空間をインポートするのを忘れずに。
using System.Web.Routing;
これで、park/xxxx.aspxにマッチするURLがリクエストされたら、park/default.aspxにplace=xxxxをクエリ引数として渡してリクエストを転送します。
default.aspxでは、Page_Loadイベントハンドラ内で、Page.RouteData.Values["place"]としてクエリを取り出せばOKです。
さて、この方式には実は問題がありまして、ルーティングもとのURLパターンが普通のASP.NETページを表しているため、すでに物理リソースが存在していれば、そちらが優先される、という点です。
つまり、shikinomori.aspxが存在していれば、default.aspx?place=shikinomoriというリクエストに置き換わりません。これはこれで問題ないのでは?とも思えますが、デバッグ中などでは、ついついshikinomori.aspxの存在を忘れて、クエリが空だ〜などとパニックになります。
こういうときには、先ほどのマッピングルールを追加する前に、物理的リソースを無視する、という指定を入れればOKです。
RouteTable.Routes.RouteExistingFiles = true;
これで、いつでもURLルーティングが可能になり、いちいち.aspxをダミーで作る必要もなく、メンテナンスが快適になりました。が、本来の使い方とはちょっと違うな、と思うので、次の機会にはもっと意味のある使い方をしてみたいと思います。
コメント