しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

ASP.NET MVC 3 開発入門 (20) - ルーティング定義を確認、追加

ASP.NET MVC 3 開発入門 - インデックス

今回、開発してきたアプリケーションの URL は以下のようになっています。

今まで開発してきて、見ただけで Video はコントローラ、Details はアクション、3 はパラメータということがなんとなくわかると思いますが、この URL は自由に変更することが出来ます。

この URL は Global.asax 内に書かれている以下のようなコードで決定されています。

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default", // ルート名
        "{controller}/{action}/{id}", // パラメーター付きの URL
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } // パラメーターの既定値
    );
}

1 行目の IgnoreRoute は無視してもらって構いません。簡単に説明すると、この URL にマッチする場合は処理を打ち切って無視するという意味になります。
重要なのはそのすぐ下にある MapRoute メソッドを呼び出している部分です。既にコメントで説明がついていますが、引数は「ルート名」「URL のパターン」「パラメータの既定値」となっています。

ルート名は今まで使ってきませんでしたが、Html.RouteLink メソッドや Url.RouteUrl メソッドが用意されているので、ルーティング定義で付けた名前を指定して利用します。

@* ルート名でリンクを作成 *@
@Html.RouteLink("リンクテキスト", "RouteName")

@* 画像リンクなど *@
<a href="@Url.RouteUrl("RouteName")"><img src="..." /></a>

URL のパターンは実際にアクセスされた URL をどのように解釈するかを定義しています。{controller} や {action} といった中括弧はパラメータとして扱われます。つまり上記のパターンの場合はスラッシュに区切られていれば空白以外を受け入れるようになっています。そして重要なのが {controller} と {action} です。この二つは特別で実際に処理されるコントローラ名とアクション名と解釈されますので、必須のパラメータとなっています。

そして最後にパラメータの既定値ですが、これはそのままの意味で URL でパラメータが指定されなかった場合に使われる値になります。つまり全て省略すると Home コントローラの Index アクションが呼び出されて処理されることになります。パラメータが指定されなかった場合には null として扱われるので、アクションの引数が値型の場合は Nullable 型として扱わないと例外が投げられるので注意してください。デフォルト値として UrlParameter.Optional を指定した時にはオプション扱いになりますので、指定されていなくてもされていても問題なく扱えるようになります。

それでは独自のルーティング定義を追加してみましょう。今回は動画サイトということなので、とある動画サイトのような URL にしてみたいと思います。具体的には以下のような URL です。

この URL で一番重要なのは数値の部分です。まず間違いなく動画のプライマリキーなので、同じようにルーティングを定義してみます。
この時注意してもらいたいのがデフォルトの定義より先に書くことです。ルーティング定義は追加した順番で優先順位が決まりますので、最初に何でも受け付ける定義を書いてしまうとせっかく追加した定義に来ることなく処理が終了してしまいます。

// /watch/mv1000000
routes.MapRoute(
    "Watch",
    "watch/mv{id}",
    new { controller = "video", action = "details" },
);

これで同じようなルーティング定義が完成しました。今回はコントローラとアクションが URL に含まれていないのであらかじめ定義しておきました。id は必須としたいのでデフォルト値を定義しないようにしました。

これだけで /watch/mv1 などという URL を叩けば表示されますが、id は数値であることが条件なので値を限定しましょう。MapRoute には 4 つの引数を取るオーバーロードが用意されているのでそちらを使います。4 つ目の引数にはパラメータの条件を正規表現などで指定できるようになっています。

// /watch/mv1000000
routes.MapRoute(
    "Watch",
    "watch/mv{id}",
    new { controller = "video", action = "details" },
    new { id = @"\d+" }
);

正規表現で \d は数字を表しますので、+ を付けて 1 桁以上の数値という制約をかけました。これで /watch/mvhauhau などといった不正な URL の場合は処理されなくなります。

それでは実際に URL を叩いて確認してみましょう。

/watch/mv3 という URL で /Video/Details/3 と同じページが表示できているのが確認できました。このように ASP.NET MVC の URL ルーティングは非常に柔軟な定義が可能になっています。正規表現で制約をかけれるので、Twitter やはてなのような /{user_id} というタイプの URL も定義できます。

次回はコードファーストで自動的に作成されたテーブルを確認して、その後実際に公開サーバへデプロイを行ってみたいと思います。お疲れ様でした。