Routing - 日本語意訳

- 2017/06/15(Thu) 時点の情報に基づいています
- 公式ドキュメント：[Routing in ASP.NET Core](https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/routing)


# ASP.NET Core の Routing

Routing 機能は、受信したリクエストを RouteHandler にマッピングする役割を担います。Route は ASP.NET アプリケーションで定義され、アプリケーションの起動時に構成されます。Route はオプションでリクエストに含まれる URL から値を抽出することができ、これらの値はリクエスト処理に使用できます。ASP.NET アプリケーションからの Route 情報を使用して、Routing 機能は RouteHandler にマッピングする URL を生成することもできます。従って、Routing は、URL に基​​づいて RouteHandler を見つけることも、または、RouteHandler 情報に基づいて、指定された RouteHandler と一致する URL を見つけることもできます。

>[!重要]
> このドキュメントは低レベルの ASP.NET Core Routing を取り扱います。ASP.NET Core MVC Routing については、[コントローラーアクションへの Routing](../mvc/controllers/routing.md) を参照してください。

[サンプルコードの参照またはダウンロード](https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/routing/sample)


## Routing の基本

Routing は *Routes* ([IRouter](https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.aspnetcore.routing.irouter) の実装) を使用して：

* 受信したリクエストを *RouteHandler* にマッピングし、

* レスポンスで使用される URL を生成します。

一般に、アプリは単一の Route コレクションを持っています。リクエストが到着すると、Route コレクションは順番に処理されます。Route コレクション内の利用可能な各 Route の `RouteAsync` メソッドを呼び出すことによって、受信したリクエストは、リクエスト URL に一致する Route を探します。対照的に、レスポンスは Route 情報に基づいて、Routing を使用して URL（例えば、リダイレクトやリンク用）を生成することができるので、このように URL をハードコードする必要がなくなり、メンテナンス性が向上します。

Routing は、`RouterMiddleware` クラスによって、Middleware パイプラインに接続されます。 [ASP.NET MVC](../mvc/overview.md) は、構成の一部として Routing を Middleware パイプラインに追加します。Routing をスタンドアロンコンポーネントとして使用する方法については、[using-routing-middleware](#using-routing-middleware) を参照してください。

<a name=url-matching-ref></a>


### URL マッチング

URL マッチングとは、Routing が受信したリクエストを *handler* に割り当てるプロセスです。このプロセスは、通常、URL パス内のデータに基づいていますが、リクエスト内のデータを考慮するように拡張できます。リクエストを個別の handler に割り当てる機能は、アプリケーションのサイズと複雑さをスケーリングするための鍵です。

受信したリクエストは `RouterMiddleware` で処理されます。`RouterMiddleware` は、各 Route の `RouteAsync` メソッドを順番に実行します。`IRouter` インスタンスは、`RouteContext.Handler` に null でない `RequestDelegate` をセットしてリクエストを*処理*するかどうかを選択します。もし Route がリクエストの handler をセットした場合、Route 処理は停止し、handler が呼び出されてリクエストが処理されます。もし全ての Route が試行され、リクエストに対する handler が見つからなければ、Middleware は *next* を実行し、リクエストパイプライン上の次の Middleware が呼び出されます。

`RouteAsync` の主なインプットは、現在のリクエストに関連付けられた`RouteContext.HttpContext` です。`RouteContext.Handler` および `RouteContext.RouteData` は、Route がマッチした後にセットされるアウトプットです。

`RouteAsync` 実行中のマッチは、これまでに行われたリクエスト処理に基づいて `RouteContext.RouteData` のプロパティに適切な値をセットします。もし Route がリクエストとマッチすれば、`RouteContext.RouteData` には *結果* に関する重要な状態情報が含まれます。

`RouteData.Values` プロパティは Route から生成された *Route値*の辞書（ディクショナリ）です。これらの値は、通常、URL をトークン化することによって決定され、ユーザーの入力を受け入れるか、アプリケーション内でさらにディスパッチするかを決定するのに使用できます。

`RouteData.DataTokens` プロパティは、マッチした Route に関連する追加データのプロパティバッグです。`DataTokens` は、状態データを各 Route に関連付けるのをサポートするのに提供されます。アプリケーションは、どの Route にマッチしたかに基づいて、後で決定することができます。これらの値は開発者が定義したものであり、Routing の振舞いには何ら影響**しません**。さらに、データトークンに格納される値は、Route値 とは対照的に、任意の型のものであってもかまいませんが、文字列と簡単に変換できなければなりません。

`RouteData.Routers` プロパティは、リクエストにマッチした Route のリストです。Route は相互にネストすることができ、`Routers` プロパティはマッチした Route の論理ツリーを経るパスを反映します。一般に、`Routers` の最初のアイテムは Route コレクションであり、URLの生成に使用されます。`Routers` の最後の項目は、マッチした RouteHandler です。


### URL の生成

URL 生成は、Routing が Route値 に基づいて URL パスを生成するプロセスです。これにより、handler とそれにアクセスする URL 間の論理的な分離が可能になります。

URL 生成は同様の反復プロセスに従いますが、Route コレクション の `GetVirtualPath` メソッドを実行するユーザーコードまたはフレームワークコードから開始します。各 *Route* で
 `GetVirtualPath` メソッドが順番に実行され、null でない `VirtualPathData` が返されるまで行われます。

`GetVirtualPath` メソッドの主なインプットは次の通りです：

* `VirtualPathContext.HttpContext`

* `VirtualPathContext.Values`

* `VirtualPathContext.AmbientValues`

Routes は、`Values` および `AmbientValues` から提供される Route値 を主に使用して、URL の生成が可能な場所と、どのような値を含めるかを決定します。`AmbientValues` は Route値 のセットで、現在のリクエストと Routing システムのマッチングにより生成されたものです。対照的に、`Values` は、現在の操作に必要な URL を生成する方法を指定するための Route値 です。Route が現在のコンテキストに関連する Service または追加データを取得する必要がある場合に備えて、`HttpContext` が提供されます。

>[!TIP]
> `Values` を `AmbientValues` のオーバーライドのセットと考えてみてください。URL 生成は、同じ Route または Route値 を使って、リンクの URL を簡単に生成できるように、現在のリクエストから Route値 を再利用しようとします。

`GetVirtualPath` メソッドのアウトプットは `VirtualPathData` です。`VirtualPathData` は `RouteData` と似ています；アウトプット URL への `VirtualPath` を含んでおり、同様に、いくつかの追加のプロパティが Route によってセットされます。

`VirtualPathData.VirtualPath` プロパティには、Route によって生成された*仮想パス*が含まれます。必要に応じて、パスをさらに処理する必要があるかもしれません。例えば、HTML 内に生成された URL をレンダリングする場合、アプリケーションの基本パスを先頭に追加する必要があります。

`VirtualPathData.Router` プロパティは、URL を正常に生成した Route への参照です。

`VirtualPathData.DataTokens` プロパティは、URLを生成した Route に関連する追加データの辞書（ディクショナリ）です。`RouteData.DataTokens` と似ています。


### Routes の生成

Routing は、`IRouter` の標準実装として `Route` クラスを提供します。`RouteAsync` が実行されたときに、`Route` は *Routeテンプレート* 構文を使用して、URL パスと一致するパターンを定義します。`GetVirtualPath` が実行されると、`Route` は同じ Routeテンプレート を使用して URL を生成します。

ほとんどのアプリケーションでは、`MapRoute` または`IRouteBuilder` で定義されている同様の拡張メソッドの1つを実行して Routes を生成します。これらのメソッドはすべて `Route` インスタンスを生成し、それを Route コレクションに追加します。

> [!注意]
> `MapRoute` は RouteHandler パラメーターを取りません - `DefaultHandler` で処理される Route のみを追加します。デフォルト handler は `IRouter` であるため、リクエストを処理しないことがあります。例えば、ASP.NET MVC は、通常、使用可能なコントローラとアクションに一致するリクエストのみを処理するデフォルト handler として構成されます。MVC の Routing の詳細については、[Routing to Controller Actions](../mvc/controllers/routing.md)を参照してください。

これは、一般的な ASP.NET MVC の Route 定義で使用される `MapRoute` 実行の例です。

```csharp:C#
Routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");
```

このテンプレートは、`/Products/Details/17` のような URL パスと一致し、Route値 `{ controller = Products, action = Details, id = 17 }` を抽出します。Route値 は、URL パスをセグメントに分割し、各セグメントを Routeテンプレート の *Routeパラメーター* 名とマッチングすることによって決定されます。Routeパラメーター には名前が付けられます。これらは、パラメーター名を中括弧 `{}` で囲むことで定義されます。

上記のテンプレートは URL パス `/` とも一致し、Route値 `{ controller = Home, action = Index }` を生成するでしょう。これは `{controller}` および `{action}` Routeパラメーター がデフォルト値を持っており、`id` Routeパラメーター がオプションであるためです。Routeパラメーター 名の後の等号 `=` は、そのあとに続く値をデフォルト値として定義します。Routeパラメーター 名の後の疑問符 `?` は、パラメーターをオプションとして定義します。Route が一致するとき、デフォルト値を持つ Routeパラメーター は、*常に* Route値 を生成します - もし一致する URL パスセグメントがななければ、オプションのパラメーターは Route値 を生成しません。

Routeテンプレート の機能と構文の詳細については、[route-template-reference](#route-template-reference) を参照してください。

この例には *Route制約 * が含まれています。

```csharp:C#
routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id:int}");
```

このテンプレートは `/Products/Details/17` のような URL パスに一致しますが、`/Products/Details/Apples` には一致しません。Routeパラメーター 定義 `{id:int}` は、`id` Route パラメーターに対して Route制約 を定義します。Route制約 は `IRouteConstraint` を実装し、Route値  を検査・検証します。この例では、Route値 `id` は整数に変換可能でなければなりません。フレームワークによって提供される Route制約 の詳細については、[route-constraint-reference](#route-constraint-reference) を参照してください。

`MapRoute` の追加のオーバーロードは、`constraints`、`dataTokens`、および `default` の値を受け入れます。 `MapRoute` のこれらの追加パラメーターは、オブジェクト型として定義されます。これらのパラメーターの一般的な使用法は、匿名型のプロパティ名が Routeパラメーター 名と一致した際に、匿名の型付きオブジェクトを渡すことです。

次の2つの例は、同等な Route を生成します：

```csharp:C#
routes.MapRoute(
    name: "default_route",
    template: "{controller}/{action}/{id?}",
    defaults: new { controller = "Home", action = "Index" });

routes.MapRoute(
    name: "default_route",
    template: "{controller=Home}/{action=Index}/{id?}");
```

>[!TIP]
> 制約とデフォルトを定義するインライン構文は、シンプルな Route にとっては便利です。ただし、データトークンなどの機能はインライン構文でサポートされていません。

この例では、さらにいくつかの機能を示します：

```csharp:C#
routes.MapRoute(
  name: "blog",
  template: "Blog/{*article}",
  defaults: new { controller = "Blog", action = "ReadArticle" });
```

このテンプレートは、`/Blog/All-About-Routing/Introduction` のような URL パスと一致し、Route値 `{ controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }` を抽出します。テンプレートに一致する Routeパラメーター がない場合でも、Route によって `controller` と `action` のデフォルト Route値 が生成されます。デフォルト値は Routeテンプレート で指定できます。`article` Routeパラメーター は、Routeパラメーター 名の前にアスタリスク `*` が付いた形の *キャッチオール* として定義されます。キャッチオール Routeパラメーターは、URL パスの残りの部分を補足し、空文字列とマッチングさせることもできます。

以下の例では、Route制約 とデータトークンが追加されています：

```csharp:C#
routes.MapRoute(
    name: "us_english_products",
    template: "en-US/Products/{id}",
    defaults: new { controller = "Products", action = "Details" },
    constraints: new { id = new IntRouteConstraint() },
    dataTokens: new { locale = "en-US" });
```

このテンプレートは、`/en-US/Products/5` のような URL パスと一致し、Route値 `{ controller = Products, action = Details, id = 5 }` と、データトークン `{ locale = en-US }` を抽出します。

![Locals Windows tokens](https://docs.microsoft.com/ja-jp/aspnet/core/fundamentals/routing/_static/tokens.png)

<a name=id1></a>


### URL の生成

`Route` クラスは、一連の Route値 とその Routeテンプレート を組み合わせて URL を生成することもできます。これは、論理的には、URL マッチングするのとは逆のプロセスです。

>[!TIP]
> URL の生成についてより良く理解するには、どんな URL を生成したいかを想像してみてください。そして、どのような Routeテンプレート がその URL にマッチするかを考えてみてください。どんな値が生成されるでしょうか？これは、Route クラス内での URL 生成の仕組みとだいたい同じです。

以下の例では、基本的な ASP.NET MVC スタイルの Route を使用します：

```csharp:C#
routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");
```

Route値 `{ controller = Products, action = List }` を使用すると、この Route は URL `/Products/List` を生成します。Route値 は、URL パスから一致する Routeパラメーター に置き換えられます。`id` はオプションの Routeパラメーター なので、値が無くても問題ありません。

Route値 `{ controller = Home, action = Index }` を使用すると、この Route は URL `/` を生成します。提供された Route値 はデフォルト値と一致しているため、これらの値に一致するセグメントは安全に省略できます。

生成された両方の URL は、どちらもこの Route 定義を使用し、URL を生成するために使用された Route値 と同じ Route値 を生成することに注意してください。

>[!TIP]
> ASP.NET MVC を使用するアプリケーションでは、直接 Routing を実行代わりに `UrlHelper` を使用して URL を生成すべきです。

URL 生成プロセスの詳細については、[url-generation-reference](#url-generation-reference) を参照してください。


## Routing Middleware の使用

NuGet パッケージ "Microsoft.AspNetCore.Routing" を追加します。

*Startup.cs* 内のサービスコンテナに Routing を追加します:

```csharp:C#
public void ConfigureServices(IServiceCollection services)
{
    services.AddRouting();
}
```

Route は、`Startup` クラスの `Configure` メソッドで設定しなければなりません。以下のサンプルでは、​​これらの API を使用しています。

* `RouteBuilder`
* `Build`
* `MapGet` は HTTP GET リクエストにのみマッチ
* `UseRouter`

<!-- literal_block {"xml:space": "preserve", "source": "fundamentals/routing/sample/RoutingSample/Startup.cs", "ids": [], "linenos": false, "highlight_args": {"linenostart": 1}} -->

```csharp:C#
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
    var trackPackageRouteHandler = new RouteHandler(context =>
    {
        var routeValues = context.GetRouteData().Values;
        return context.Response.WriteAsync(
            $"Hello! Route values: {string.Join(", ", routeValues)}");
    });

    var routeBuilder = new RouteBuilder(app, trackPackageRouteHandler);

    routeBuilder.MapRoute(
        "Track Package Route",
        "package/{operation:regex(^track|create|detonate$)}/{id:int}");

    routeBuilder.MapGet("hello/{name}", context =>
    {
        var name = context.GetRouteValue("name");
        // This is the RouteHandler when HTTP GET "hello/<anything>"  matches
        // To match HTTP GET "hello/<anything>/<anything>,
        // use routeBuilder.MapGet("hello/{*name}"
        return context.Response.WriteAsync($"Hi, {name}!");
    });

    var routes = routeBuilder.Build();
    app.UseRouter(routes);
}
```

次の表は、指定された URI へのレスポンスを示しています。

| URI | Response  |
| ------- | -------- |
| /package/create/3  | Hello! Route values: [operation, create], [id, 3] |
| /package/track/-3  | Hello! Route values: [operation, track], [id, -3] |
| /package/track/-3/ | Hello! Route values: [operation, track], [id, -3]  |
| /package/track/ | \<不成立, マッチしない> |
| GET /hello/Joe | Hi, Joe! |
| POST /hello/Joe | \<不成立, HTTP GET にのみマッチする> |
| GET /hello/Joe/Smith | \<不成立, マッチしない> |

もし単一の Route を構成している場合は、`IRouter` インスタンスを渡して `app.UseRouter` を実行してください。 `RouteBuilder` を実行する必要はありません。

フレームワークは次のような Route を生成する拡張メソッドのセットを提供します：

* `MapRoute`
* `MapGet`
* `MapPost`
* `MapPut`
* `MapDelete`
* `MapVerb`

`MapGet` などのメソッドの中には、`RequestDelegate` の提供を必要とするものがあります。`RequestDelegate` は、Route がマッチしたときに RouteHandler として使用されます。このファミリーの他のメソッドは、RouteHandler として使用される Middleware パイプラインを構成できます。もし `Map` メソッドが `MapRoute などのハンドラを受け入れない場合は、`DefaultHandler` を使用します。

`Map[Verb]` メソッドは、制約を使用して、[Verb] に該当する HTTP メソッド へ Route を制限します。例えば、[MapGet](https://github.com/aspnet/Routing/blob/1.0.0/src/Microsoft.AspNetCore.Routing/RequestDelegateRouteBuilderExtensions.cs#L85-L88) と [MapVerb](https://github.com/aspnet/Routing/blob/1.0.0/src/Microsoft.AspNetCore.Routing/RequestDelegateRouteBuilderExtensions.cs#L156-L180) を参照してください。


## Routeテンプレート の参照

中括弧（`{}`）内のトークンは、Route が一致した場合にバインドされる *Routeパラメーター* を定義します。1つの Route セグメントに複数の Routeパラメーター を定義できますが、それらはリテラル値で区切らなければなりません。例えば、`{controller}` と `{action}` の間にはリテラル値がないので、`{controller = Home}{action = Index}` は有効な Route ではありません。これらの Routeパラメーター には名前が必須で、追加の属性が指定されていることもあります。

Routeパラメーター 以外のリテラルテキスト（例えば、`{id}`）とパス区切り文字 `/` は、URL のテキストと一致しなければなりません。テキストマッチングは、大文字と小文字を区別せず、URL パスのデコードされた表現に基づいています。Routeパラメーター のデリミタである `{` または `}` をリテラル値としてマッチングさせるには、文字を重ねてエスケープします（`{{` または `}}`）。

オプションのファイル拡張子を使用してファイル名を補足しようとする URL パターンには、さらに考慮事項があります。例えば、テンプレート `fles/{filename}.{ext?}` を使用すると - `filename` と `ext` の両方が存在する場合、両方の値が格納されます。 URL に `filename` のみが存在する場合でも Route はマッチします。なぜなら、末尾のピリオド `.` がオプションのためです。次の URL がこの Route に一致します：

* `/files/myFile.txt`
* `/files/myFile.`
* `/files/myFile`

`*` 文字を Routeパラメーター の接頭辞として使用して、URI の残りの部分にバインドすることができます - これはキャッチオールパラメーターと呼ばれます。例えば、`blog/{*slug}` は `/blog` で始まり、かつ、それに続く値（`slug` Route値 に割り当てられる）を持つどんな URI ともマッチします。キャッチオールパラメーターは、空文字列ともマッチします。

Routeパラメーター はデフォルト値を持つことができ、パラメーター名の後にデフォルトを指定し、`=` で区切って指定します。例えば、`{controller=Home}` は、`controller` のデフォルト値として `Home` を定義します。もし、パラメーターの値が URL に存在しなければ、デフォルト値が使用されます。デフォルト値に加えて、Routeパラメーター はオプションでもかまいません（ `id?` のようにパラメーター名の最後に `?` を付けて指定します）。オプションと "デフォルトあり" の違いは、デフォルト値を持つ Routeパラメーター は常に値を生成することです；オプションのパラメーターは、値が提供された場合にのみ値を持ちます。

Routeパラメーター は制約を持つことがあり、その制約とは URL からバインドされた Route値 とマッチしなければならないというものです。Routeパラメーター 名の後にコロン `:` と制約名を追加することで、Routeパラメーター に対してインライン制約が指定されます。制約が引数を必要とする場合は、制約名の後に括弧 `()` で囲んで指定します。複数のインライン制約は、別のコロン `:` と制約名を追加することで指定できます。制約名は `IInlineConstraintResolver` サービスに渡されて `IRouteConstraint` のインスタンスが生成され、URL 処理で使用されます。例えば、Routeテンプレート `blog/{article:minlength(10)}` は、引数 `10` の `minlength` 制約を指定します。Route制約 とフレームワークによって提供される制約のリストについて詳しくは、[route-constraint-reference](#route-constraint-reference) を参照してください。

次の表は、いくつかの Routeテンプレート とその動作を示します。

| Route Template | Example Matching URL | Notes |
| -------- | -------- | ------- |
| hello  | /hello  | 単一パス `/hello` にのみマッチ |
| {Page=Home} | / | マッチし、`Page` に `Home` をセット |
| {Page=Home}  | /Contact  | マッチし、`Page` に `Contact` をセット |
| {controller}/{action}/{id?} | /Products/List | `Products` コントローラーと `List`  アクションにマッピング |
| {controller}/{action}/{id?} | /Products/Details/123  |  `Products` コントローラーと `Details` アクションにマッピング。`id` には 123 をセット |
| {controller=Home}/{action=Index}/{id?} | /  | `Home` コントローラーと `Index` アクションにマッピング。 `id` は無視。 |

一般に、テンプレートを使用するのが最も簡単な Routing 方法です。制約とデフォルトは、Routeテンプレート の外で指定することもできます。

>[!TIP]
> [Logging](logging.md) を有効にすると、Route などの組み込みの Routing 実装がどのようにリクエストとマッチするかを確認できます。


## Route制約 の参照

Route制約 は、Route が受信した URL の構文と一致し、URL パスを Route値 にトークン化したときに実行されます。Route制約 は、一般に、Routeテンプレート を介して関連付けられた Route値 を検査し、その値が許容可能かどうかについてシンプルな yes/no 判定を行います。一部の Route制約 では、Route値 以外のデータを使用して、リクエストが Routing できるかどうかを検討します。例えば、`HttpMethodRouteConstraint` はHTTP メソッドに基づいてリクエストを受け入れまたは拒否することができます。

>[!警告]
> **入力検証**に制約を使用しないでください。なぜなら、無効な入力が、適切なエラーメッセージを持つ 400 ではなく、404（Not Found）になることを意味するためです。Route制約 は、特定の Route の入力を検証するためではなく、類似の Route 間の曖昧さを排除するために使用すべきです。

次の表は、いくつかの Route制約 と期待される動作を示しています。

| constraint | Example | Example Matches | Notes |
| --------   | ------- | ------------- | ----- |
| `int` | `{id:int}` | `123456789`, `-123456789`  | 任意の数値にマッチ |
| `bool`  | `{active:bool}` | `true`, `FALSE` | `true` または `false` にマッチ (大文字小文字を区別しない) |
| `datetime` | `{dob:datetime}` | `2016-12-31`, `2016-12-31 7:32pm`  | 有効な `DateTime` 値にマッチ (不変のカルチャ - 警告を参照) |
| `decimal` | `{price:decimal}` | `49.99`, `-1,000.01` | 有効な  `decimal` 値にマッチ (不変のカルチャ - 警告を参照) |
| `double`  | `{weight:double}` | `1.234`, `-1,001.01e8` | 有効な `double` 値にマッチ (不変のカルチャ - 警告を参照) |
| `float`  | `{weight:float}` | `1.234`, `-1,001.01e8` | 有効な `float` 値にマッチ (不変のカルチャ - 警告を参照) |
| `guid`  | `{id:guid}` | `CD2C1638-1638-72D5-1638-DEADBEEF1638`, `{CD2C1638-1638-72D5-1638-DEADBEEF1638}` | Matches a valid `Guid` value |
| `long` | `{ticks:long}` | `123456789`, `-123456789` | 有効な `long` 値にマッチ |
| `minlength(value)` | `{username:minlength(4)}` | `Rick` | 文字列4文字以上 |
| `maxlength(value)` | `{filename:maxlength(8)}` | `Richard` | 文字列8文字以上 |
| `length(length)` | `{filename:length(12)}` | `somefile.txt` | 文字列12文字 |
| `length(min,max)` | `{filename:length(8,16)}` | `somefile.txt` | 文字列8文字以上16文字以下 |
| `min(value)` | `{age:min(18)}` | `19` | 数値18以上 |
| `max(value)` | `{age:max(120)}` |  `91` | 数値120以下 |
| `range(min,max)` | `{age:range(18,120)}` | `91` | 数値18以上120以下 |
| `alpha` | `{name:alpha}` | `Rick` | 文字列1つ以上のアルファベット（a-z、大文字小文字を区別しない） |
| `regex(expression)` | `{ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)}` | `123-45-6789` | 文字列は正規表現とマッチ（正規表現の定義に関するヒントを参照） |
| `required`  | `{name:required}` | `Rick` |  URL生成中にパラメータ以外の値が存在することを強制するために使用される |

>[!警告]
> URL を CLR 型（`int` や `DateTime` など）に変換できるかどうかを確認する Route制約 は、常に不変のカルチャを使用します - URL がローカライズされていないと仮定しています。フレームワーク提供の Route制約 は、Route値 に格納された値を変更しません。URL から解析された Route値 は全て文字列として格納されます。例えば、[Float route constraint](https://github.com/aspnet/Routing/blob/1.0.0/src/Microsoft.AspNetCore.Routing/Constraints/FloatRouteConstraint.cs#L44-L60) は Route値  を float に変換しようとしますが、変換された値は float に変換できるかどうかを検証するためにのみ使用されます。


## 正規表現

ASP.NET Core フレームワークは `RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant` を正規表現コンストラクタに追加します。これらのメンバーの説明については、[RegexOptions Enumeration](https://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regexoptions(v=vs.110).aspx) を参照してください。

正規表現では、Routing や C# 言語で使用されるものと同様のデリミタとトークンが使用されます。正規表現トークンはエスケープされなければなりません。例えば、Routing で正規表現 `^ \d{3}-\d{2}-\d{4}$` を使用するには、C# ソースファイルで `\` を `\\` に入力して、`\` 文字列エスケープ文字（[逐語的文字列リテラル](https://msdn.microsoft.com/en-us/library/aa691090(v=vs.71).aspx) を使用しない限り）。Routing パラメーターのデリミタをエスケープするには、`{` 、`}`、 '[' と ']' 文字を重ねる必要があります。以下の表では、正規表現とそのエスケープバージョンを示しています。

| Expression               | Note |
| ----------------- | ------------ | 
| `^\d{3}-\d{2}-\d{4}$` | 正規表現 |
| `^\\d{{3}}-\\d{{2}}-\\d{{4}}$` | エスケープバージョン  |
| `^[a-z]{2}$` | 正規表現 |
| `^[[a-z]]{{2}}$` | エスケープバージョン |

Routing で使用される正規表現は、通常 `^` 文字（文字列の開始位置にマッチ）で始まり、`$` 文字（文字列の終了位置にマッチ）で終わります。`^` と `$` 文字は、正規表現が Routeパラメーター 値全体と一致することを保証します。`^` と `$` 文字がないと、正規表現は文字列内の部分文字列とも一致するでしょう。これはしばしば期待するものではありません。以下の表では、いくつかの例を示し、それらが合致する理由と合致しない理由を説明します。

| Expression               | String | Match | Comment |
| ----------------- | ------------ |  ------------ |  ------------ | 
| `[a-z]{2}` | hello | yes | 部分文字列が一致 |
| `[a-z]{2}` | 123abc456 | yes | 部分文字列が一致 |
| `[a-z]{2}` | mz | yes | 完全一致 |
| `[a-z]{2}` | MZ | yes | 大文字小文字は区別されていない |
| `^[a-z]{2}$` |  hello | no | 上記の `^` と `$` を参照 |
| `^[a-z]{2}$` |  123abc456 | no | 上記の `^` と `$` を参照 |

正規表現の構文の詳細については、[.NET Framework Regular Expressions](https://msdn.microsoft.com/en-us/library/hs600312(v=vs.110).aspx) を参照してください。

パラメーターを既知の可能な値のセットに制限するには、正規表現を使用します。例えば、`{action:regex(^(list|get|create)$)}` は、`list`、`get`、または `create` への `action` Route値 にのみマッチします。制約辞書に渡された場合、文字列  "^(list|get|create)$" は同等です。既知の制約の1つと一致しない制約辞書（テンプレート内のインラインではない）に渡される制約も、正規表現として扱われます。


## URL 生成の参照

次の例は、Route値 の辞書と `RouteCollection` が与えられた Route へのリンクを生成する方法を示しています。

```csharp:C#
app.Run(async (context) =>
{
    var dictionary = new RouteValueDictionary
    {
        { "operation", "create" },
        { "id", 123}
    };

    var vpc = new VirtualPathContext(context, null, dictionary, "Track Package Route");
    var path = routes.GetVirtualPath(vpc).VirtualPath;

    context.Response.ContentType = "text/html";
    await context.Response.WriteAsync("Menu<hr/>");
    await context.Response.WriteAsync($"<a href='{path}'>Create Package 123</a><br/>");
});
```

上記のサンプルの最後に生成された `VirtualPath` は /package/create/123` です。

`VirtualPathContext` コンストラクタの2番目のパラメーターは、アンビエント値のコレクションです。 アンビエント値は、特定のリクエストコンテキスト内で開発者が指定しなければならない値の数を制限することにより、便利さを提供します。現在のリクエストの現在の Route値 はリンク生成のためのアンビエント値と見なされます。例えば、ASP.NET MVC アプリケーションで `HomeController` の `About` アクションを実行している場合、`Index` アクションにリンクしたコントローラの Route値 を指定する必要はありません（`Home` のアンビエント値が使用されます）。

パラメーターとマッチしないアンビエント値は無視されます。また、明示的に指定された値でオーバーライドされた場合も、アンビエント値は無視されます。

明示的に指定されているものの、何も一致しない値はクエリ文字列に追加されます。以下の表は、Routeテンプレート `{controller}/{action}/{id?}` を使用した場合の結果を示したものです。

| Ambient Values | Explicit Values | Result |
| -------------   | -------------- | ------ |
| controller="Home" | action="About" | `/Home/About` |
| controller="Home" | controller="Order",action="About" | `/Order/About` |
| controller="Home",color="Red" | action="About" | `/Home/About` |
| controller="Home" | action="About",color="Red" | `/Home/About?color=Red`

Route がパラメーターにマッチしないデフォルト値を持っていて、その値が明示的に指定されている場合は、デフォルト値と一致しなければなりません。例えば：

```csharp:C#
routes.MapRoute("blog_route", "blog/{*slug}",
  defaults: new { controller = "Blog", action = "ReadPost" });
```

リンク生成は、コントローラとアクションに対してマッチする値が提供された場合にのみ、このルートのリンクを生成します。