- 2017/06/15(Thu) 時点の情報に基づいています
- 公式ドキュメント:Routing in ASP.NET Core
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 を参照してください。
Routing の基本
Routing は Routes (IRouter の実装) を使用して:
-
受信したリクエストを RouteHandler にマッピングし、
-
レスポンスで使用される URL を生成します。
一般に、アプリは単一の Route コレクションを持っています。リクエストが到着すると、Route コレクションは順番に処理されます。Route コレクション内の利用可能な各 Route の RouteAsync
メソッドを呼び出すことによって、受信したリクエストは、リクエスト URL に一致する Route を探します。対照的に、レスポンスは Route 情報に基づいて、Routing を使用して URL(例えば、リダイレクトやリンク用)を生成することができるので、このように URL をハードコードする必要がなくなり、メンテナンス性が向上します。
Routing は、RouterMiddleware
クラスによって、Middleware パイプラインに接続されます。 ASP.NET MVC は、構成の一部として Routing を Middleware パイプラインに追加します。Routing をスタンドアロンコンポーネントとして使用する方法については、using-routing-middleware を参照してください。
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を参照してください。
これは、一般的な ASP.NET MVC の Route 定義で使用される MapRoute
実行の例です。
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制約 * が含まれています。
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 を参照してください。
MapRoute
の追加のオーバーロードは、constraints
、dataTokens
、および default
の値を受け入れます。 MapRoute
のこれらの追加パラメーターは、オブジェクト型として定義されます。これらのパラメーターの一般的な使用法は、匿名型のプロパティ名が Routeパラメーター 名と一致した際に、匿名の型付きオブジェクトを渡すことです。
次の2つの例は、同等な Route を生成します:
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 にとっては便利です。ただし、データトークンなどの機能はインライン構文でサポートされていません。
この例では、さらにいくつかの機能を示します:
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制約 とデータトークンが追加されています:
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 }
を抽出します。
URL の生成
Route
クラスは、一連の Route値 とその Routeテンプレート を組み合わせて URL を生成することもできます。これは、論理的には、URL マッチングするのとは逆のプロセスです。
[!TIP]
URL の生成についてより良く理解するには、どんな URL を生成したいかを想像してみてください。そして、どのような Routeテンプレート がその URL にマッチするかを考えてみてください。どんな値が生成されるでしょうか?これは、Route クラス内での URL 生成の仕組みとだいたい同じです。
以下の例では、基本的な ASP.NET MVC スタイルの Route を使用します:
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 を参照してください。
Routing Middleware の使用
NuGet パッケージ "Microsoft.AspNetCore.Routing" を追加します。
Startup.cs 内のサービスコンテナに Routing を追加します:
public void ConfigureServices(IServiceCollection services)
{
services.AddRouting();
}
Route は、Startup
クラスの Configure
メソッドで設定しなければなりません。以下のサンプルでは、これらの API を使用しています。
RouteBuilder
Build
-
MapGet
は HTTP GET リクエストにのみマッチ UseRouter
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 と MapVerb を参照してください。
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テンプレート とその動作を示します。
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 を有効にすると、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 は Route値 を float に変換しようとしますが、変換された値は float に変換できるかどうかを検証するためにのみ使用されます。
正規表現
ASP.NET Core フレームワークは RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant
を正規表現コンストラクタに追加します。これらのメンバーの説明については、RegexOptions Enumeration を参照してください。
正規表現では、Routing や C# 言語で使用されるものと同様のデリミタとトークンが使用されます。正規表現トークンはエスケープされなければなりません。例えば、Routing で正規表現 ^ \d{3}-\d{2}-\d{4}$
を使用するには、C# ソースファイルで \
を \\
に入力して、\
文字列エスケープ文字(逐語的文字列リテラル を使用しない限り)。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 を参照してください。
パラメーターを既知の可能な値のセットに制限するには、正規表現を使用します。例えば、{action:regex(^(list|get|create)$)}
は、list
、get
、または create
への action
Route値 にのみマッチします。制約辞書に渡された場合、文字列 "^(list|get|create)$" は同等です。既知の制約の1つと一致しない制約辞書(テンプレート内のインラインではない)に渡される制約も、正規表現として扱われます。
URL 生成の参照
次の例は、Route値 の辞書と RouteCollection
が与えられた Route へのリンクを生成する方法を示しています。
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 がパラメーターにマッチしないデフォルト値を持っていて、その値が明示的に指定されている場合は、デフォルト値と一致しなければなりません。例えば:
routes.MapRoute("blog_route", "blog/{*slug}",
defaults: new { controller = "Blog", action = "ReadPost" });
リンク生成は、コントローラとアクションに対してマッチする値が提供された場合にのみ、このルートのリンクを生成します。