Help us understand the problem. What is going on with this article?

ASP.NET Core MVC 3.1 入門 その4 「Routing」

はじめに

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とすると、なぜHelloControllerIndexアクションメソッドが呼び出されるのかを理解する
  • デフォルトのRouteを変更できるようになる

環境

IDE
Visual Studio 2019
言語
C#

前提

以下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?}");
            });
        }
    }

挙動を確認する

実行してみると、以下のようにHomeControllerIndexアクションメソッドが呼び出されています。理由は後述します。

image.png

ここでアドレスバーから手入力でURLを変更します。
変更前は以下のようになっているかと思います。
XXXXXの部分はポート番号を示しています。
環境とタイミング次第で異なりますので、ご自身の画面に表示されているものから変更する必要はありません。

https://localhost:XXXXX/

以下のようにアドレスバーから手入力でURLを変更してください。
末尾にHello/Indexを追加します。

https://localhost:XXXXX/Hello/Index

変更後、Enterを押下すると、以下のように「Hello World!」が表示されると思います。
これはつまり、HelloControllerIndexアクションメソッドが呼び出されています。

image.png

ここで生じた2つの疑問について、仕組みを説明していきます。

  • 実行すると、なぜHomeControllerIndexアクションメソッドが呼び出されるのか
  • Hello/Indexとすると、なぜHelloControllerIndexアクションメソッドが呼び出されるのか

Routing

クライアントから要求されたURLに応じて、呼び出すコントローラーやアクションを決定する仕組みのことです。
ASP.NET Core MVC では、クライアントからの要求を受け取ると、まずは、Routingを利用して、呼び出すべきコントローラー(アクションメソッド)を決定します。

Routingの流れ

  1. リクエストのURLをアプリケーションが定義しているルート(Route)と照合します。
  2. 一致するルートが見つかった場合は、該当するコントローラーのアクションメソッドが呼び出されます。
    ※見つからなければ、404(NotFound)エラーとなります。
https://localhost:XXXXX/Hello/Index

従ってHelloControllerIndexアクションメソッドが呼び出されるのは、上記のURLをルートと照合した結果、一致するルートが見つかったからということになります。

ルート(Route)

では、ルートとはどこでどのように定義されているのでしょうか。

ルートとは、URLからどのコントローラーに処理を関連づけるかのパターンマッチング文字列です。
プロジェクト直下のStartup.csConfigureメソッド)で定義されています。

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}はプレースホルダーです。
controlleractionは予約されている名前で、それぞれコントローラー名と
アクションメソッド名と紐づきます。
{id}にはアクションメソッドに渡される任意のパラメーターを設定することができます。

従って~/Home/Index/5であればHomeControllerIndexアクションメソッドを呼び出し、パラメーターとして5を渡す という意味になります。

patternの省略(デフォルト値)

では、説明を飛ばした=Homeidに付与されている?の意味も確認しておきましょう。

デフォルト値

省略された場合のデフォルト値を用意しておきたいならば、{controller=Home}のように書きます。(「=」以降がデフォルト値です)
上記の通り設定していた場合http://localhost:XXXXXとすると、コントローラー名とアクション名が省略されているため、デフォルト値が効いて、HomeControllerIndexアクションメソッドが呼び出されることになります。

  • コントローラー名とアクション名を省略してみる image.png

省略可能なパラメーター

{id?}の「?」は、そのパラメーターが省略できることを示しています。
{controller}/{action}/{id?}であれば、Home/Index/5のようなパスだけでなく、Home/Indexでもマッチします。

  • idを省略してみる image.png

デフォルトのルートを変更してみる

MapControllerRouteメソッドを以下のように修正します。

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllerRoute(
            name: "default",
            pattern: "{controller=Hello}/{action=Index}/{id?}"); //Home => Hello
    });

実行すると、コントローラー名とアクション名が省略されているため、デフォルト値が効いて、HelloControllerIndexアクションメソッドが呼び出されています

image.png

以上となります。
ありがとうございました。

yagi405
C#とASP.NET Core MVCが好きです。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away