.NET TIPS [ASP.NET MVC]ルート定義を追加するには?[3.5、4、C#、VB]山田 祥寛2010/07/08 |
|
ルーティングとは、リクエスト時のURIに応じて処理の受け渡し先(コントローラ)を決定すること、または、その仕組みのことだ。ASP.NET MVCでは、デフォルトでルーティングが有効になっており、最初のうちはルーティングを利用していくことを意識すらしないかもしれない。そうした意味で、ルーティングとはASP.NET MVCの挙動の根幹を支える仕組みといってもよいだろう*1。
*1 だからといって、ルーティングがASP.NET MVC固有の仕組みというわけではない。ASP.NET本体でもルーティングを利用することは可能である。 |
本稿では、このルーティングを定義するための基本的な方法(構文)について解説する。
●ルート定義の基本
手始めに、ASP.NET MVCデフォルトで用意されているルーティング・ルール(ルート)を確認してみよう。ルートを定義しているのは、Global.asaxの役割である。
|
||
デフォルトで用意されているルート定義(上:Global.asax.cs、下:Global.asax.vb) |
RegisterRoutesメソッドはアプリケーション起動(Startイベント・ハンドラ)のタイミングで呼び出されるメソッドで、デフォルトのルート(名前はDefault)を追加している。
ルートを追加するには、ルートの集合を表すRouteCollectionオブジェクトからMapRouteメソッドを呼び出すだけだ。MapRouteメソッドの構文は、次のとおりである。
|
|
MapRouteメソッドの構文 | |
name:ルート名。 url:URIパターン。 defaults:初期値。 |
引数urlは、ルーティングに際して、実際にマッチさせるURIパターンを表すものだ。例えば、Defaultルートでは、以下のようなパターンが定義されている。
{controller}/{action}/{id} |
{名前}の部分は変数のプレイスホルダで、{controller}はコントローラ名、{action}はアクション名、{id}はアクション・メソッドに引き渡される任意のパラメータ(ユーザー・パラメータ)を、それぞれ表す。
{controller}/{action}はあらかじめ決められた名前であるので、勝手に変更することはできないが、{id}は必要に応じて適宜変更しても構わない。
これら変数のデフォルト値を指定しているのが、引数defaultsだ。Defaultルートでは、
|
のように記述しているので、
controller = Home
action = Index
id = 任意(ブランクも可)
であると見なされるわけだ。つまり、この設定においては、それぞれ以下のURLでは以下のように認識されることになる。
リクエストURL | controller | action | id |
http://localhost:8080/Book/Details/12345 | Book | Details | 12345 |
http://localhost:8080/Book/Create | Book | Create | (ブランク) |
http://localhost:8080/Book | Book | Index | (ブランク) |
http://localhost:8080/ | Home | Index | (ブランク) |
リクエストURLとパラメータにセットされる値 |
●アプリケーション固有のルート定義を追加する
ルート定義の基本が理解できたところで、具体的な例を挙げながら自作のルート定義を追加してみよう。なお、ルート経由で取得したパラメータ値を確認するために、あらかじめ以下のようなRoute/Indexアクションを定義しておくものとする。
|
||
ルート・パラメータを列挙するためのアクション・メソッド(上:RouteController.cs、下:RouteController.vb) |
*2 ここではサンプルという便宜上、アクション・メソッドで直接に出力を生成しているが、本来、コントローラでは出力を担当するべきでない。 |
ルート・パラメータは、RouteDataプロパティにアクセスすることで取得できる。ここでは、そのValuesプロパティから個別のパラメータを取り出し、順に出力しているわけだ。ルート・パラメータの扱いについては、「ASP.NET MVCフレームワーク 基本のキ」も併せてご参照いただきたい。
(1)複数のパラメータを受け取るルート定義
前述したように、パラメータは自由に設定して構わない。例えば、以下のように複数のパラメータを受け取ることも可能だ。
|
||
複数のパラメータを受け取るMultiルートを定義するコード(上:Global.asax.cs、下:Global.asax.vb) |
ここではfirst、secondと2つのパラメータを定義しているが、もちろん、必要に応じて3個以上のパラメータを定義しても構わないし、そもそも{controller}、{action}が先頭にくる必要もない。例えば、
{first}/{controller}/{action}/{second} |
のようなパターンも妥当なURIパターンである。
Multiルートではデフォルト値を定義していない点にも注目だ。前述したように、デフォルト値が定義されているパラメータは省略可能となる。つまり、デフォルト値が定義されていないということは、すべてのパラメータは省略「できない」ということである。
このルートに対して、次のアドレスでアクセスした場合の結果は、以下のとおりである。
|
|
|
|
上記のアドレスでアクセスした場合の結果 |
(2){controller}/{action}パラメータを持たないルート定義
そもそもURIパターンに{controller}、{action}パラメータを含まないルートを定義しても構わない。
|
||
URIパターンに{controller}、{action}を含まないArticleルートを定義するコード(上:Global.asax.cs、下:Global.asax.vb) |
URIパターンに{controller}、{action}を含まない場合、引数defaultsによる{controller}、{action}のデフォルト値の設定は必須となる(さもないと、処理を委譲すべきコントローラ/アクション名が特定できないからだ)。
また、ここではデフォルト値にリテラルではなく、式を指定している点にも注目だ(リストの太字部分)。これによって、{year}/{month}/{day}パラメータが省略された場合、それぞれ現在の年月日がセットされることになる。
以下に、リクエストURLとパラメータ値の関係をまとめておく。
リクエストURL | controller | action | day | month | year |
/Article/25/06/2009 | Route | Index | 25 | 06 | 2009 |
/Article/25/06 | Route | Index | 25 | 06 | 2010 |
/Article/25 | Route | Index | 25 | 2 | 2010 |
/Article | Route | Index | 24 | 2 | 2010 |
リクエストURLとパラメータにセットされる値(今日が2010/02/24の場合) |
(3)パラメータの区切り文字を「-」に
パラメータの区切り文字は何も「/」である必要はない。例えば、以下は(2)のURIパターンを「-」区切りで書き換えたものである(書き換え部分は太字で表している)。
|
||
パラメータを「-」以外で区切った場合のコード(上:Global.asax.cs、下:Global.asax.vb) |
確かに、
http://localhost:8080/Article/25-06-2009.html
のようなアドレスでアクセスできることを確認しておこう。もちろん、区切り文字の「-」は「.」(ピリオド)でも、それどころか「X」のようなアルファベットでも構わない。ただし、アルファベットや数値を区切り文字として利用することは、マッチするURLを分かりにくくする原因にだけでなく、思わぬURLがマッチしてしまう原因でもあるので、原則として避けるべきだ。通常は、パラメータの区切り文字は「/」「-」「_」「.」あたりに止めておくのが望ましいだろう。
また、パラメータの間にそもそも区切り文字が入らない、
"Article/{day}{month}{year}.html",
のようなパターンは認められない。
(4)任意の数のパラメータを渡す場合
特殊なパラメータの表記として{*名前}のように記述することもできる。
|
||
複数のパラメータを受け取るMultiルートを定義するコード(上:Global.asax.cs、下:Global.asax.vb) |
{*名前}は、以降のすべての値をそのパラメータに吸収するという意味である。例えば、このルートに対して、次のアドレスでアクセスした場合の結果は、以下のとおりである。
|
|
|
|
Multiルートの定義に対して上記のアドレスでアクセスした場合の結果 |
「Many/〜」以降のすべての値がparamにセットされていることが確認できるだろう。
ちなみに、URIパターンを「Many/{param}」のようにアスタリスク(*)抜きにした場合には「/Many/12345」にはマッチするが、「/Many/12345/67890」「/Many/12345/67890/XYZ」などにはマッチしなくなる。
{*名前}のパターンは、不特定多数のパラメータを受け取りたい場合(あらかじめパラメータの数が特定できない場合)に利用できるだろう。
なお、アスタリスク付きのパラメータは、その性質上、URIパターンの末尾でしか利用できないので、注意されたい(アスタリスクがすべて吸収してしまうため、以降のパラメータが値を受け取ることは絶対にないためだ)。
利用可能バージョン:.NET Framework 3.5 利用可能バージョン:.NET Framework 4 カテゴリ: ASP.NET MVC 処理対象:ルーティング |
「.NET TIPS」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|