はじめに
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
- 言語
- C#
前提
以下2つのコントローラークラスが存在するものとします。
いずれもテキストデータを返すだけのIndexアクションメソッドが定義されています。
アクションメソッドについては、前回の記事を参照してください。
publicclassHelloController:Controller{publicIActionResultIndex(){returnContent("Hello World!");}}publicclassHomeController:Controller{publicIActionResultIndex(){returnContent("Home");}}StartUpクラスはテンプレートのままです。
publicclassStartup{//省略publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv){//省略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はアプリケーションを起動する際に呼び出されるメソッドで、アプリの基本設定を宣言する場所ですね。
publicclassStartup{//省略publicvoidConfigure(IApplicationBuilderapp,IWebHostEnvironmentenv){//省略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アクションメソッドが呼び出されています
以上となります。
ありがとうございました。



