はじめに
ASP.NET Core MVC 3.1 の Routing について、自分が学んだことを備忘録として記載します。
このフレームワークに殆ど触れたことが無い方に少しでも参考になれば幸いです。
誤り等あれば、ご指摘頂けますと大変喜びます。
前回の記事
ASP.NET Core MVC 3.1 入門 その3 「Controller」
今回の流れ
- 挙動の確認
- Routingの説明
- Routeの説明
- Routeの定義
- デフォルトのRouteを変更してみる
今回のゴール
- Routingとは何かを知る
-
https://localhost:XXXXX/Hello/Index
とすると、なぜHelloController
のIndex
アクションメソッドが呼び出されるのかを理解する - デフォルトのRouteを変更できるようになる
環境
- IDE
- Visual Studio 2019
<dt>言語</dt>
<dd>C#</dd>
前提
以下2つのコントローラークラスが存在するものとします。
いずれもテキストデータを返すだけのIndex
アクションメソッドが定義されています。
アクションメソッドについては、前回の記事を参照してください。
public class HelloController : Controller
{
public IActionResult Index()
{
return Content("Hello World!");
}
}
public class HomeController : Controller
{
public IActionResult Index()
{
return Content("Home");
}
}
StartUp
クラスはテンプレートのままです。
public class Startup
{
//省略
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//省略
app.UseRouting();
//省略
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
}
挙動を確認する
実行してみると、以下のようにHomeController
のIndex
アクションメソッドが呼び出されています。理由は後述します。
ここでアドレスバーから手入力でURLを変更します。
変更前は以下のようになっているかと思います。
XXXXX
の部分はポート番号を示しています。
環境とタイミング次第で異なりますので、ご自身の画面に表示されているものから変更する必要はありません。
https://localhost:XXXXX/
以下のようにアドレスバーから手入力でURLを変更してください。
末尾にHello/Index
を追加します。
https://localhost:XXXXX/Hello/Index
変更後、Enterを押下すると、以下のように「Hello World!」が表示されると思います。
これはつまり、HelloController
のIndex
アクションメソッドが呼び出されています。
ここで生じた2つの疑問について、仕組みを説明していきます。
- 実行すると、なぜ
HomeController
のIndex
アクションメソッドが呼び出されるのか -
Hello/Index
とすると、なぜHelloController
のIndex
アクションメソッドが呼び出されるのか
Routing
クライアントから要求されたURLに応じて、呼び出すコントローラーやアクションを決定する仕組みのことです。
ASP.NET Core MVC では、クライアントからの要求を受け取ると、まずは、Routingを利用して、呼び出すべきコントローラー(アクションメソッド)を決定します。
Routingの流れ
- リクエストのURLをアプリケーションが定義しているルート(Route)と照合します。
- 一致するルートが見つかった場合は、該当するコントローラーのアクションメソッドが呼び出されます。
※見つからなければ、404(NotFound)エラーとなります。
https://localhost:XXXXX/Hello/Index
従ってHelloController
のIndex
アクションメソッドが呼び出されるのは、上記のURLをルートと照合した結果、一致するルートが見つかったからということになります。
ルート(Route)
では、ルートとはどこでどのように定義されているのでしょうか。
ルートとは、URLからどのコントローラーに処理を関連づけるかのパターンマッチング文字列です。
プロジェクト直下のStartup.cs
(Configure
メソッド)で定義されています。
Configure
はアプリケーションを起動する際に呼び出されるメソッドで、アプリの基本設定を宣言する場所ですね。
public class Startup
{
//省略
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//省略
app.UseRouting();
//省略
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Hello}/{action=Index}/{id?}");
});
}
}
UseRouting
メソッドによって、Routingを有効化しています。
有効化されていない状態で実際の振り分け先を決めるUseEndpoints
メソッドを呼び出すとエラーになります。
ルートを定義しているのは、MapControllerRoute
メソッドです。
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
MapControllerRouteメソッド
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
-
name
default
の部分
設定を識別するための名前です。
一意でさえあれば自由に設定可能です。
この時点では、複数設定できるということだけ抑えておけば問題ありません。 -
pattern
{controller=Home}/{action=Index}/{id?}
の部分
ルーティングの際にマッチングをおこなうためのURLパターンを示す文字列です。
pattern
{controller=Home}/{action=Index}/{id?}
とありますが
まずはシンプルに
{controller}/{action}/{id}
と解釈してください。
{XXX}
はプレースホルダーです。
controller
とaction
は予約されている名前で、それぞれコントローラー名と
アクションメソッド名と紐づきます。
{id}
にはアクションメソッドに渡される任意のパラメーターを設定することができます。
従って~/Home/Index/5
であればHomeController
のIndex
アクションメソッドを呼び出し、パラメーターとして5
を渡す という意味になります。
patternの省略(デフォルト値)
では、説明を飛ばした=Home
やid
に付与されている?
の意味も確認しておきましょう。
デフォルト値
省略された場合のデフォルト値を用意しておきたいならば、{controller=Home}
のように書きます。(「=
」以降がデフォルト値です)
上記の通り設定していた場合http://localhost:XXXXX
とすると、コントローラー名とアクション名が省略されているため、デフォルト値が効いて、HomeController
のIndex
アクションメソッドが呼び出されることになります。
省略可能なパラメーター
{id?}
の「?
」は、そのパラメーターが省略できることを示しています。
{controller}/{action}/{id?}
であれば、Home/Index/5
のようなパスだけでなく、Home/Index
でもマッチします。
デフォルトのルートを変更してみる
MapControllerRoute
メソッドを以下のように修正します。
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Hello}/{action=Index}/{id?}"); //Home => Hello
});
実行すると、コントローラー名とアクション名が省略されているため、デフォルト値が効いて、HelloController
のIndex
アクションメソッドが呼び出されています
以上となります。
ありがとうございました。