1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[メモ] ルーティング

Last updated at Posted at 2020-08-20

はじめに

ASP.NET Core のルーティングについて調べたときのメモです。

環境

$ dotnet --version
3.1.401

ルーティングを使えるようにする

ミドルウェアパイプラインに UseRouting と UseEndpoints を追加する。
(デフォルトで追加されるので、あまり気にする必要ない)

Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        // コントローラーで定義したアクションをエンドポイントに追加する
        endpoints.MapControllers();
    });
}

ルーティングの定義方法

ASP.NET Coreでルートを定義する方法は二つある。
Attribute routing vs conventional routing

  • 属性ルーティング - REST APIを構築する場合に使う
  • 従来のルーティング - ブラウザ用のhtmlページを提供する場合に使う (こっちは自分には必要無いので今回は調べない)

ルートの結合

コントローラに設定したルートとアクションに設定したルートは結合される。
https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-3.1#combining-attribute-routes

using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("products")]
public class ProductsApiController : ControllerBase
{
    [Route] // e.g. https://localhost:5001/products/
    [Route("{id}")] // e.g. https://localhost:5001/products/100
    public ActionResult<string> GetProduct(int? id)
    {
        return ControllerContext.HttpContext.Request.Path.ToString();
    }
}

ただし、アクションのルートがスラッシュ(/)またはチルダとスラッシュ(~/)から始まる場合は結合されない。

using Microsoft.AspNetCore.Mvc;

[Route("Home")]
public class HomeController : Controller
{
    [Route("Index")] // e.g https://localhost:5001/Home/Index
    [Route("/Index")] // e.g https://localhost:5001/Index
    [Route("/")] // e.g https://localhost:5001/
    public ActionResult<string> Index()
    {
        return ControllerContext.HttpContext.Request.Path.ToString();
    }

    [Route("About")] // e.g https://localhost:5001/Home/About
    [Route("~/About")] // e.g https://localhost:5001/About
    public ActionResult<string> About()
    {
        return ControllerContext.HttpContext.Request.Path.ToString();
    }
}
  • RouteAttributeについて
  • HTTPメソッドは区別されない。マッチしたアクションが呼び出される。
  • アクションが処理するHTTPメソッドを指定するにはGetAttributeなどを使う。

ルートパラメータ

一つのルートセグメントの中に複数のルートパラメータを設定することができる。
ただし、各ルートパラメータはリテラルで区切る必要がある。

{controller=Home}{action=Index} <- 区切られていないのでダメ
{controller=Home}abc{action=Index} <- リテラル'abc'で区切られているのでおk
  • セグメント・・・ パス区切り(/)で区切られた範囲。
    https://localhost:5001/weatherforecast/{a}b{c}ならセグメントはweatherforecast{a}b{c}の2つ。

セグメントの中にオプションパラメータ(?付きのパスパラメータ)を設定する場合は、区切り文字としてドット(.)を使う。(他の文字は使用できない)

https://localhost:5001/weatherforecast/{filename}.{ext?} <- おk
https://localhost:5001/weatherforecast/{filename}-{ext?} <- '.'じゃない('-'区切りになっている)のでダメ

ターミナルミドルウェア

ルートの照合を行うミドルウェアのこと。
ランタイムが提供するルーティング機能を使用せずに実装することは推奨されない。
ルートの照合処理の実装は相当の手間が掛かる。
Map, MapWhen と組み合わせることで、ルートの照合処理とミドルウェアの機能を分離した方が良い。

参考

NOTE: You may only have one optional parameter per route, and that optional parameter must be the last parameter.

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?