ASP.NET CoreのMVCルーティング1

6994 ワード

1.はじめに


ASP.NET Core MVCは、ルーティングミドルウェアを使用して、入力要求のURLに一致し、それらを動作にマッピングする(Actionメソッド).ルーティングは、スタートアップコード(Startup.configureメソッド)またはプロパティ(Controller Actionプロパティ)で定義されます.ルーティングは、URLパスをアクション(Actionメソッド)とどのように一致させるかを説明します.また、応答中に送信されたURLを生成するためにも使用されます.ルーティング操作は、ミドルウェアを設定し、従来のルーティング、属性理由(Controller Actionに理由を置くことで実現可能)、複数のルーティングをサポートすることができる.

2.ルーティングミドルウェアの設定


Configureメソッドでは、ルーティングミドルウェアコードが以下のように設定されている場合があります.
app.UseMvc(routes =>
{
    routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
});

に等しい
//       "{controller=Home}/{action=Index}/{id?}"
app.UseMvcWithDefaultRoute();

UseMvcの匿名メソッドでは、MapRouteは単一のルーティングの作成を表し、デフォルト(default)ルーティング、ルーティングテンプレート({controller=Home}/{action=Index}/{id?})として指定される.ルーティングテンプレート"{controller=Home}/{action=Index}/{id?}"「/Home/Index/5」のURLパスにマッチすることを意味します.すなわち,●{controller=Home}はHomeをデフォルトのcontrollerとして定義する.●{action=Index}Indexをデフォルトactionとして定義します.●{id?}idをオプションパラメータとして定義します.UseMvcおよびUseMvcWithDefaultRouteは、RouterMiddlewareのインスタンスをミドルウェアパイプに追加します.MVCは,ミドルウェアと直接対話するのではなく,ルーティングを用いて要求を処理する.MVCは、MvcRouteHandlerインスタンスを介してルーティングに接続される.UseMvc(Action)を再ロードすると、ユーザーは独自のルーティングを追加でき、属性ルーティングもサポートされます.UseMvcWithDefaultRouteはデフォルトのルーティングを定義し、属性ルーティングをサポートします.

3.従来のルーティング


デフォルトのルーティング:routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}"); 上記のコードは従来のルーティングであり、この方法を従来のルーティングと呼ぶのは、URLパスに、●第1のパスセグメントがコントローラ名にマッピングされる●第2のセグメントが操作名にマッピングされるという約束が設けられているからである.・第3のセグメントは、モデルエンティティにマッピングするためのオプションidに使用される.このdefaultルーティングを使用すると、URLパス/Home/IndexがHomeControllerにマッピングされる.Index.このマッピングは、名前空間、ソースファイルの場所、またはメソッドパラメータに基づいていないコントローラおよびアクション名のみに基づいています.

4.複数のルーティング


4.1複数のルーティングの定義


UseMvc匿名メソッドに複数のルーティングを追加することで、特定の操作に特化した複数の規則を定義したり、従来のルーティングを追加したりすることができます.たとえば、次のようになります.
app.UseMvc(routes =>
{
    //     
    routes.MapRoute("blog", "blog/{*article}",defaults: new { controller = "Blog", action = "Article" });
    //     
    routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});

最初のルーティングでは、catch-allルーティングパラメータを使用してURLパスの残りの部分をキャプチャすることを示します.次に、テストによって検証します.
●"blog/{*article}":
●"blog/{article}":
以上のテストから,アスタリスク付きルーティングはパラメータ文字列にスラッシュを付けても開くことができ,アスタリスクを付けていないルーティングはパラメータ文字列にスラッシュを付けては開くことができないことが分かった.もう一つ注意したいのはcontrollerですAction受信パラメータは*の後のパラメータ名と一致する必要があります.そうしないと、パラメータ値が受信されません.

4.2区分操作


コントロールに2つのアクション名が一致するメソッドがある場合、MVCは区別する必要があります.そうしないと、例外が発生します.たとえば、次のようにします.
public class BlogController : Controller
{
    public IActionResult Edit(int id) {}
    [HttpPost]
    public IActionResult Edit(int id, Blog blog) {}
}

要求がHTTP POSTの場合、MVCはEdit(int,Blog)を選択し、Http属性が他のコンテンツの場合はEdit(int)を選択する.複数のルーティングが一致し、MVCが「最適」ルーティングアクションが見つからない場合、AmbiguousActionException例外が発生します.

5.属性ルーティング


5.1属性ルーティング


属性ルーティングは、一連の属性を使用して、操作(Action)をルーティングテンプレートに直接マッピングします.以下の例では、Configureメソッドはappを用いる.UseMvc()は、ルーティングを伝達しません.HomeControllerは、デフォルトのルーティング{controller=Home}/{action=Index}/{id?}と一致するURLのセットを作成します.一致するURL類似:
public class HomeController : Controller
{
   [Route("")]
   [Route("Home")]
   [Route("Home/Index")]
   public IActionResult Index()
   {
      return View();
   }
}

次に、各プロパティルーティングがブラウザでリンクを開くのにどのような効果があるかを表で見てみましょう.
Route Template
Browser
Page
Route("")
[SERVICE_NAME]
[SERVICE_NAME]/Home/Index
Route("Home")
[SERVICE_NAME]/Home
Route("Home/Index")
[SERVICE_NAME]/Home/Index
3つの属性ルーティングはブラウザ上でリンクを開く方法は異なりますが、プレゼンテーションページは同じです.つまり、3つの属性ルーティングの定義方法は同じ/Home/Indexページを指します.ここまで来ると、もし私が3つの属性ルーティングテンプレートの名前を変更したら、同じページを開くことができますか?
[Route("1")]
[Route("Home1")]
[Route("Home1/Index1")]

上記のテンプレート名は変更されましたが、ブラウザでページを表示するか、/Home/indexを指すか、つまり、プロパティルーティングテンプレート名がどのように変更されても対応する/Home/indexページが開きます.

5.2 Http[Verb]属性を用いた属性ルーティング


属性ルーティングでは、HttpPostAttributeなどのHttp[Verb]属性も使用できます.これらのプロパティはすべてルーティングテンプレートを使用できます.この例では、同じルーティングテンプレートと一致する2つのアクションを示します.
public class BlogController : Controller
{
    [HttpGet("/article/{id}", Name = "Article_List")]
    public IActionResult Article(string id)
    {
        return View();
    }
}

ブラウザに[SERVICE_NAME]/article/1を入力すると、DEBUGで応答結果が表示されます.
応答結果から、属性ルーティングは、まず、ルーティング属性定義のルーティングテンプレートセット([HttpGet("/article/{id},Name="Article_List")とURLを一致させることが分かる.ルーティングテンプレートが一致すると、IActionConstraint制約が適用され、実行可能なアクションが決定されます.

5.3連結ルーティング


ビジネスシーンに基づいて、Controllerの下のすべてのactionにアクセスするためにControllerの名前を変更する必要がある場合は、どのように設定しますか?以下に例を示します.
[Route("homes")]
public class HomeController : Controller
{
    [HttpGet("{id}")]
    public IActionResult Index()
    {
       return View();
    }
}

上記のコードに従って、HomeController上にルーティング属性([Route])を配置すると、コントローラ内のすべての操作(Action)がその属性ルーティングを使用します.つまり、IndexビューにアクセスできるのはURL HTTPGet:[SERVICE_NAME]/homs/1のみです.この方法の利点は、HomeControllerの下の各アクションがRoute(「homes」)属性を単独で追加する必要がなく、HomeControllerの外にグローバルRoute(「homes」)属性を1つ置くだけで各アクションに適用され、ルーティング属性の重複を減らすことである.

5.4属性ルーティングのオプションパラメータ、デフォルト値、制約を指定する


属性ルーティングは、従来のルーティングと同じインライン構文を使用して、オプションのパラメータ、デフォルト値、および制約を指定することもサポートします.次に例を示します.
public class HomeController : Controller
{
    [HttpGet("homes/{id:int}")]
    public IActionResult Index(int id)
    {
        return View();
    }
}

上記のコードの実行結果を表で確認します.
Browser
Result status
[SERVICE_NAME]/homes/1
200
[SERVICE_NAME]/homes/qwe
404
[HttpGet(「homes/{id:int}」)は、入力idパラメータ値を数値のみが属性の下のビューを開くように制約し、入力が文字列である場合はビューを見つけることができません.詳細なルーティング制約テンプレートは、ここで参照してください.

5.4カスタム属性ルーティング


ルーティング属性は、フレームワークに付属するIrouteTemplateProviderインタフェースを使用してカスタマイズできます(たとえば、[HttpGet]、[Route(「homes」)などの属性).アプリケーションが起動すると、MVCはコントローラクラスと操作方法のプロパティを検索し、IrouteTemplateProviderを実装するプロパティを使用して初期ルーティングのセットを生成します.このセクションでは、アプリケーションのカスタム属性ルーティングの使用方法を簡単な例で説明します.
public class MyControllerAttribute : Attribute, IRouteTemplateProvider
{
    //         ,   [controller]       。
    public string Template => "api/[controller]/{action}/{id?}";
    public int? Order { get; set; }
    public string Name { get; set; }
}

ルーティング属性クラスカスタム属性パスを新規作成し、ControlまたはActionにカスタム属性ルーティングを配置します.
public class BlogController : Controller
{
    [MyController()]
    public IActionResult Article(string id)
    {
        return View();
    }
}

[SERVICE_NAME]/api/Blog/article/1リンクの実行中にアクセスできました.つまり、カスタム属性ルーティングに成功しました.
参考文献:ASP.NET Coreでのコントローラ操作へのルーティング
(8)ASP.NET CoreのMVCルーティング1