ASP.NET Core 中的路由Routing in ASP.NET Core

作者:Ryan NowakSteve SmithRick AndersonBy Ryan Nowak, Steve Smith, and Rick Anderson

如需本主題的 1.1 版,請下載 ASP.NET Core 中的路由 (1.1 版,PDF)For the 1.1 version of this topic, download Routing in ASP.NET Core (version 1.1, PDF).

路由功能負責將要求 URI 對應至端點選取器,並將傳入要求分派給端點。Routing is responsible for mapping request URIs to endpoint selectors and dispatching incoming requests to endpoints. 路由定義於應用程式,並在該應用程式啟動時進行設定。Routes are defined in the app and configured when the app starts. 路由可以選擇性地從要求中所包含的 URL 擷取值,然後這些值就可用於處理要求。A route can optionally extract values from the URL contained in the request, and these values can then be used for request processing. 使用應用程式中的路由資訊,路由功能也能夠產生對應至端點選取器的 URL。Using route information from the app, routing is also able to generate URLs that map to endpoint selectors.

若要使用 ASP.NET Core 2.2 中的最新路由情節,請將相容性版本指定為 Startup.ConfigureServices 中的 MVC 服務註冊:To use the latest routing scenarios in ASP.NET Core 2.2, specify the compatibility version to the MVC services registration in Startup.ConfigureServices:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

EnableEndpointRouting 選項會決定路由功能應該在內部使用以端點為基礎的邏輯,或以 IRouter 為基礎的邏輯 (適用於 ASP.NET Core 2.1 或更舊版本)。The EnableEndpointRouting option determines if routing should internally use endpoint-based logic or the IRouter-based logic of ASP.NET Core 2.1 or earlier. 當相容性版本設定為 2.2 或更新版本時,預設值為 trueWhen the compatibility version is set to 2.2 or later, the default value is true. 將值設定為 false 可使用舊版路由邏輯:Set the value to false to use the prior routing logic:

// Use the routing logic of ASP.NET Core 2.1 or earlier:
services.AddMvc(options => options.EnableEndpointRouting = false)
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

如需以 IRouter 為基礎之路由的詳細資訊,請參閱本主題的 ASP.NET Core 2.1 版本For more information on IRouter-based routing, see the ASP.NET Core 2.1 version of this topic.

路由功能負責將要求 URI 對應至路由處理常式,並分派傳入要求。Routing is responsible for mapping request URIs to route handlers and dispatching an incoming requests. 路由定義於應用程式,並在該應用程式啟動時進行設定。Routes are defined in the app and configured when the app starts. 路由可以選擇性地從要求中所包含的 URL 擷取值,然後這些值就可用於處理要求。A route can optionally extract values from the URL contained in the request, and these values can then be used for request processing. 使用應用程式中已設定的路由,路由功能將能夠產生對應至路由處理常式的 URL。Using configured routes from the app, routing is able to generate URLs that map to route handlers.

若要使用 ASP.NET Core 2.1 中的最新路由情節,請將相容性版本指定為 Startup.ConfigureServices 中的 MVC 服務註冊:To use the latest routing scenarios in ASP.NET Core 2.1, specify the compatibility version to the MVC services registration in Startup.ConfigureServices:

services.AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

重要

本文件涵蓋低階的 ASP.NET Core 路由。This document covers low-level ASP.NET Core routing. 如需 ASP.NET Core MVC 路由的資訊,請參閱 ASP.NET Core 中的路由至控制器動作For information on ASP.NET Core MVC routing, see ASP.NET Core 中的路由至控制器動作. 如需 Razor Pages 中路由慣例的資訊,請參閱 ASP.NET Core 中的 Razor 頁面路由和應用程式慣例For information on routing conventions in Razor Pages, see ASP.NET Core 中的 Razor 頁面路由和應用程式慣例.

檢視或下載範例程式碼 (英文) (如何下載)View or download sample code (how to download)

路由的基本概念Routing basics

大部分應用程式都應該選擇基本的描述性路由傳送配置,讓 URL 可讀且有意義。Most apps should choose a basic and descriptive routing scheme so that URLs are readable and meaningful. 預設慣例路由 {controller=Home}/{action=Index}/{id?}The default conventional route {controller=Home}/{action=Index}/{id?}:

  • 支援基本的描述性路由配置。Supports a basic and descriptive routing scheme.
  • 適合作為 UI 型應用程式的起點。Is a useful starting point for UI-based apps.

在特殊情況下,開發人員通常會使用屬性路由或專屬的慣例路由,新增額外的簡潔路由到應用程式的高流量區域 (例如,部落格和電子商務端點)。Developers commonly add additional terse routes to high-traffic areas of an app in specialized situations (for example, blog and ecommerce endpoints) using attribute routing or dedicated conventional routes.

Web API 應該使用屬性路由傳送來將應用程式功能模型建構為作業由 HTTP 指令動詞代表的資源集合。Web APIs should use attribute routing to model the app's functionality as a set of resources where operations are represented by HTTP verbs. 這表示相同邏輯資源上的許多作業 (例如,GET、POST) 都會使用相同的 URL。This means that many operations (for example, GET, POST) on the same logical resource will use the same URL. 屬性路由提供仔細設計 API 公用端點配置所需的控制層級。Attribute routing provides a level of control that's needed to carefully design an API's public endpoint layout.

Razor Pages 應用程式使用預設慣例路由,來提供應用程式 Pages 資料夾中的具名資源。Razor Pages apps use default conventional routing to serve named resources in the Pages folder of an app. 還有其他慣例可讓您自訂 Razor Pages 路由行為。Additional conventions are available that allow you to customize Razor Pages routing behavior. 如需詳細資訊,請參閱 ASP.NET Core 中的 Razor Pages 簡介ASP.NET Core 中的 Razor 頁面路由和應用程式慣例For more information, see ASP.NET Core 中的 Razor Pages 簡介 and ASP.NET Core 中的 Razor 頁面路由和應用程式慣例.

URL 產生支援允許在不需要硬式編碼的 URL 來連結應用程式的情況下開發應用程式。URL generation support allows the app to be developed without hard-coding URLs to link the app together. 這項支援可讓您從基本路由設定開始,並在決定應用程式資源配置之後修改路由。This support allows for starting with a basic routing configuration and modifying the routes after the app's resource layout is determined.

路由功能使用「端點」 (Endpoint) 來表示應用程式中的邏輯端點。Routing uses endpoints (Endpoint) to represent logical endpoints in an app.

端點會定義用來處理要求的一項委派及一個任意中繼資料集合。An endpoint defines a delegate to process requests and a collection of arbitrary metadata. 中繼資料可根據附加至每個端點的原則和組態,來實作跨領域關注。The metadata is used implement cross-cutting concerns based on policies and configuration attached to each endpoint.

路由系統具有下列特性:The routing system has the following characteristics:

  • 使用路由範本語法以 Token 化路由參數來定義路由。Route template syntax is used to define routes with tokenized route parameters.

  • 允許傳統式和屬性式端點組態。Conventional-style and attribute-style endpoint configuration is permitted.

  • IRouteConstraint 可用來判斷 URL 參數是否包含對指定端點條件約束有效的值。IRouteConstraint is used to determine whether a URL parameter contains a valid value for a given endpoint constraint.

  • 應用程式模型 (例如 MVC/Razor Pages) 會註冊其所有端點,這些端點的路由情節實作符合預期。App models, such as MVC/Razor Pages, register all of their endpoints, which have a predictable implementation of routing scenarios.

  • 路由實作會在中介軟體管線需要時制定路由決策。The routing implementation makes routing decisions wherever desired in the middleware pipeline.

  • 在路由中介軟體之後出現的中介軟體可以檢查指定要求 URI 的路由中介軟體端點決策。Middleware that appears after a Routing Middleware can inspect the result of the Routing Middleware's endpoint decision for a given request URI.

  • 您可以針對中介軟體管線中任何位置的應用程式,列舉其中的所有端點。It's possible to enumerate all of the endpoints in the app anywhere in the middleware pipeline.

  • 應用程式可以根據端點資訊使用路由來產生 URL (例如,針對重新導向或連結),因此避免硬式編碼的 URL,這有助於可維護性。An app can use routing to generate URLs (for example, for redirection or links) based on endpoint information and thus avoid hard-coded URLs, which helps maintainability.

  • URL 是根據支援任意擴充性的位址所產生:URL generation is based on addresses, which support arbitrary extensibility:

注意

在 ASP.NET Core 2.2 中發行端點路由時,端點連結限制在 MVC/Razor Pages 動作和頁面。With the release of endpoint routing in ASP.NET Core 2.2, endpoint linking is limited to MVC/Razor Pages actions and pages. 未來版本將規劃擴充端點連結功能。The expansions of endpoint-linking capabilities is planned for future releases.

路由 (routing) 功能會使用「路由」(route) (IRouter 的實作) 來:Routing uses routes (implementations of IRouter) to:

  • 將傳入要求對應至「路由處理常式」 。Map incoming requests to route handlers.
  • 產生用於回應的 URL。Generate the URLs used in responses.

根據預設,應用程式有一個路由集合。By default, an app has a single collection of routes. 當要求抵達時,集合中的路由會依其存在於集合的順序進行處理。When a request arrives, the routes in the collection are processed in the order that they exist in the collection. 此架構會嘗試對集合中的每個路由呼叫 RouteAsync 方法,藉以比對傳入要求 URL 與集合中的路由。The framework attempts to match an incoming request URL to a route in the collection by calling the RouteAsync method on each route in the collection. 回應可以根據路由資訊使用路由來產生 URL (例如,針對重新導向或連結),因此避免硬式編碼的 URL,這有助於可維護性。A response can use routing to generate URLs (for example, for redirection or links) based on route information and thus avoid hard-coded URLs, which helps maintainability.

路由系統具有下列特性:The routing system has the following characteristics:

  • 使用路由範本語法以 Token 化路由參數來定義路由。Route template syntax is used to define routes with tokenized route parameters.
  • 允許傳統式和屬性式端點組態。Conventional-style and attribute-style endpoint configuration is permitted.
  • IRouteConstraint 可用來判斷 URL 參數是否包含對指定端點條件約束有效的值。IRouteConstraint is used to determine whether a URL parameter contains a valid value for a given endpoint constraint.
  • 應用程式模型 (例如 MVC/Razor Pages) 會註冊其所有路由,這些路由的路由情節實作符合預期。App models, such as MVC/Razor Pages, register all of their routes, which have a predictable implementation of routing scenarios.
  • 回應可以根據路由資訊使用路由來產生 URL (例如,針對重新導向或連結),因此避免硬式編碼的 URL,這有助於可維護性。A response can use routing to generate URLs (for example, for redirection or links) based on route information and thus avoid hard-coded URLs, which helps maintainability.
  • URL 是根據支援任意擴充性的路由所產生。URL generation is based on routes, which support arbitrary extensibility. IUrlHelper 提供方法來建立 URL。IUrlHelper offers methods to build URLs.

路由會透過 RouterMiddleware 類別連線到中介軟體管線。Routing is connected to the middleware pipeline by the RouterMiddleware class. ASP.NET Core MVC 會將路由新增至中介軟體管線,作為其組態的一部分,並處理 MVC 和 Razor Pages 應用程式中的路由。ASP.NET Core MVC adds routing to the middleware pipeline as part of its configuration and handles routing in MVC and Razor Pages apps. 若要了解如何使用路由作為獨立元件,請參閱使用路由中介軟體一節。To learn how to use routing as a standalone component, see the Use Routing Middleware section.

URL 比對URL matching

URL 比對是路由用來將傳入要求分派給「端點」 的處理序。URL matching is the process by which routing dispatches an incoming request to an endpoint. 這個處理序是基於 URL 路徑中的資料,但是可以擴展為考慮要求中的任何資料。This process is based on data in the URL path but can be extended to consider any data in the request. 分派要求給不同處理常式的能力,是調整應用程式大小和複雜度的關鍵。The ability to dispatch requests to separate handlers is key to scaling the size and complexity of an app.

當路由中介軟體執行時,它會將端點 (Endpoint) 和路由值設定為 HttpContext 上的功能。When a Routing Middleware executes, it sets an endpoint (Endpoint) and route values to a feature on the HttpContext. 針對目前的要求:For the current request:

  • 呼叫 HttpContext.GetEndpoint 可取得端點。Calling HttpContext.GetEndpoint gets the endpoint.
  • HttpRequest.RouteValues 會取得路由值的集合。HttpRequest.RouteValues gets the collection of route values.

在路由中介軟體之後執行的中介軟體可以看到端點,並採取動作。Middleware running after the Routing Middleware can see the endpoint and take action. 例如,授權中介軟體可以針對授權原則,查閱端點的中繼資料集合。For example, an Authorization Middleware can interrogate the endpoint's metadata collection for an authorization policy. 執行要求處理管線中的所有中介軟體之後,會叫用所選端點的委派。After all of the middleware in the request processing pipeline is executed, the selected endpoint's delegate is invoked.

端點路由中的路由系統負責制定所有分派決策。The routing system in endpoint routing is responsible for all dispatching decisions. 由於中介軟體會根據所選取的端點來套用原則,因此請務必在路由系統內制定可能影響分派或應用安全性原則的任何決策。Since the middleware applies policies based on the selected endpoint, it's important that any decision that can affect dispatching or the application of security policies is made inside the routing system.

執行端點委派時,會根據到目前為止所執行的要求處理,將 RouteContext.RouteData 的屬性設定為適當的值。When the endpoint delegate is executed, the properties of RouteContext.RouteData are set to appropriate values based on the request processing performed thus far.

URL 比對是路由用來將傳入要求分派給「處理常式」 的處理序。URL matching is the process by which routing dispatches an incoming request to a handler. 這個處理序是基於 URL 路徑中的資料,但是可以擴展為考慮要求中的任何資料。This process is based on data in the URL path but can be extended to consider any data in the request. 分派要求給不同處理常式的能力,是調整應用程式大小和複雜度的關鍵。The ability to dispatch requests to separate handlers is key to scaling the size and complexity of an app.

傳入要求將進入 RouterMiddleware,而後者會依序在每個路由上呼叫 RouteAsync 方法。Incoming requests enter the RouterMiddleware, which calls the RouteAsync method on each route in sequence. IRouter 執行個體可將 RouteContext.Handler 設定為非 Null 的 RequestDelegate,來選擇是否要「處理」 要求。The IRouter instance chooses whether to handle the request by setting the RouteContext.Handler to a non-null RequestDelegate. 如果路由為要求設定了處理常式,則路由處理會停止,且會叫用該處理常式來處理要求。If a route sets a handler for the request, route processing stops, and the handler is invoked to process the request. 如果找不到處理要求的路由處理常式,中介軟體會將要求傳遞給要求管線中的下一個中介軟體。If no route handler is found to process the request, the middleware hands the request off to the next middleware in the request pipeline.

RouteAsync 的主要輸入是與目前要求建立關聯的 RouteContext.HttpContextThe primary input to RouteAsync is the RouteContext.HttpContext associated with the current request. RouteContext.HandlerRouteContext.RouteData 是在比對路由之後設定的輸出。The RouteContext.Handler and RouteContext.RouteData are outputs set after a route is matched.

呼叫 RouteAsync 的比對也會根據到目前為止所執行的要求處理,將 RouteContext.RouteData 的屬性設定為適當的值。A match that calls RouteAsync also sets the properties of the RouteContext.RouteData to appropriate values based on the request processing performed thus far.

RouteData.Values 是「路由值」 的字典,而路由值產生自路由。RouteData.Values is a dictionary of route values produced from the route. 這些值通常是透過將 URL 語彙基元化來決定,可以用來接受使用者輸入,或在應用程式內做出進一步的分派決策。These values are usually determined by tokenizing the URL and can be used to accept user input or to make further dispatching decisions inside the app.

RouteData.DataTokens 是其他資料的屬性包,而這些資料與相符路由相關。RouteData.DataTokens is a property bag of additional data related to the matched route. 提供了 DataTokens 來支援與每個路由建立關聯的狀態資料,因此應用程式可以依據符合哪一個路由來制定決策。DataTokens are provided to support associating state data with each route so that the app can make decisions based on which route matched. 這些是開發人員定義的值,不會以任何方式影響路由的行為。These values are developer-defined and do not affect the behavior of routing in any way. 此外,儲藏在 RouteData.DataTokens 中的值可以是任何類型,對比之下,RouteData.Values 則必須可轉換成字串或可從字串轉換。Additionally, values stashed in RouteData.DataTokens can be of any type, in contrast to RouteData.Values, which must be convertible to and from strings.

RouteData.Routers 是成功符合要求的參與路由清單。RouteData.Routers is a list of the routes that took part in successfully matching the request. 路由可以用巢狀方式置於彼此內部。Routes can be nested inside of one another. Routers 屬性會透過導致產生相符項目的路由邏輯樹狀結構反映路徑。The Routers property reflects the path through the logical tree of routes that resulted in a match. 一般而言,Routers 中的第一個項目是路由集合,應該用於產生 URL。Generally, the first item in Routers is the route collection and should be used for URL generation. Routers 中的最後一個項目是相符的路由處理常式。The last item in Routers is the route handler that matched.

使用 LinkGenerator 產生 URLURL generation with LinkGenerator

URL 產生是路由可用來依據一組路由值建立 URL 路徑的處理序。URL generation is the process by which routing can create a URL path based on a set of route values. 這可讓您在端點和存取它們的 URL 之間建立邏輯分隔。This allows for a logical separation between your endpoints and the URLs that access them.

端點路由包含連結產生器 API (LinkGenerator)。Endpoint routing includes the Link Generator API (LinkGenerator). LinkGenerator 是可從 DI 擷取的單一服務。LinkGenerator is a singleton service that can be retrieved from DI. 您可以在執行要求內容外部使用此 API。The API can be used outside of the context of an executing request. MVC 的 IUrlHelper 及依賴 IUrlHelper 的情節 (例如標籤協助程式、HTML 協助程式和動作結果) 均使用連結產生器來提供連結產生功能。MVC's IUrlHelper and scenarios that rely on IUrlHelper, such as Tag Helpers, HTML Helpers, and Action Results, use the link generator to provide link generating capabilities.

連結產生器背後支援的概念為「位址」 和「位址配置」 。The link generator is backed by the concept of an address and address schemes. 位址配置可讓您判斷應考慮用於連結產生的端點。An address scheme is a way of determining the endpoints that should be considered for link generation. 例如,MVC/Razor Pages 中許多使用者所熟悉的路由名稱和路由值情節,都會實作為位址配置。For example, the route name and route values scenarios many users are familiar with from MVC/Razor Pages are implemented as an address scheme.

連結產生器可以透過下列擴充方法,連結至 MVC/Razor Pages 動作和頁面:The link generator can link to MVC/Razor Pages actions and pages via the following extension methods:

這些方法的多載接受包含 HttpContext 的引數。An overload of these methods accepts arguments that include the HttpContext. 這些方法的功能等同於 Url.ActionUrl.Page,但提供更多彈性和選項。These methods are functionally equivalent to Url.Action and Url.Page but offer additional flexibility and options.

GetPath* 方法與 Url.ActionUrl.Page 最類似,因為它們會產生包含絕對路徑的 URI。The GetPath* methods are most similar to Url.Action and Url.Page in that they generate a URI containing an absolute path. GetUri* 方法一律會產生包含配置和主機的絕對 URI。The GetUri* methods always generate an absolute URI containing a scheme and host. 接受 HttpContext 的方法會在執行要求的內容中產生 URI。The methods that accept an HttpContext generate a URI in the context of the executing request. 除非遭到覆寫,否則會使用來自執行要求的環境路由值、URL 基底路徑、配置和主機。The ambient route values, URL base path, scheme, and host from the executing request are used unless overridden.

呼叫 LinkGenerator 並指定一個位址。LinkGenerator is called with an address. 執行下列兩個步驟來產生 URI:Generating a URI occurs in two steps:

  1. 將位址繫結至符合該位址的端點清單。An address is bound to a list of endpoints that match the address.
  2. 評估每個端點的 RoutePattern,直到找到符合所提供值的路由模式。Each endpoint's RoutePattern is evaluated until a route pattern that matches the supplied values is found. 產生的輸出會與提供給連結產生器的其他 URI 組件合併並傳回。The resulting output is combined with the other URI parts supplied to the link generator and returned.

LinkGenerator 提供的方法支援適用於任何位址類型的標準連結產生功能。The methods provided by LinkGenerator support standard link generation capabilities for any type of address. 使用連結產生器的最便利方式是透過執行特定位址類型作業的擴充方法。The most convenient way to use the link generator is through extension methods that perform operations for a specific address type.

擴充方法Extension Method 說明Description
GetPathByAddress 根據提供的值產生具有絕對路徑的 URI。Generates a URI with an absolute path based on the provided values.
GetUriByAddress 根據提供的值產生絕對 URI。Generates an absolute URI based on the provided values.

警告

注意呼叫 LinkGenerator 方法的下列影響:Pay attention to the following implications of calling LinkGenerator methods:

  • 使用 GetUri* 擴充方法,並注意應用程式組態不會驗證傳入要求的 Host 標頭。Use GetUri* extension methods with caution in an app configuration that doesn't validate the Host header of incoming requests. 如果傳入要求的 Host 標頭未經驗證,則可能將未受信任的要求輸入傳回檢視/頁面 URI 中的用戶端。If the Host header of incoming requests isn't validated, untrusted request input can be sent back to the client in URIs in a view/page. 建議所有生產應用程式將其伺服器設定為驗證 Host 標頭是否為已知有效值。We recommend that all production apps configure their server to validate the Host header against known valid values.

  • 使用 LinkGenerator,並注意與 MapMapWhen 搭配使用的中介軟體。Use LinkGenerator with caution in middleware in combination with Map or MapWhen. Map* 會變更執行要求的基底路徑,這會影響連結產生的輸出。Map* changes the base path of the executing request, which affects the output of link generation. 所有的 LinkGenerator API 都允許指定基底路徑。All of the LinkGenerator APIs allow specifying a base path. 請一律指定空白基底路徑來恢復 Map* 對連結產生的影響。Always specify an empty base path to undo Map*'s affect on link generation.

與舊版路由的差異Differences from earlier versions of routing

ASP.NET Core 2.2 或更新版本中的端點路由與 ASP.NET Core 中的舊版路由之間有一些差異:A few differences exist between endpoint routing in ASP.NET Core 2.2 or later and earlier versions of routing in ASP.NET Core:

  • 端點路由系統不支援以 IRouter 為基礎的擴充性,包括從 Route 繼承。The endpoint routing system doesn't support IRouter-based extensibility, including inheriting from Route.

  • 端點路由不支援 WebApiCompatShimEndpoint routing doesn't support WebApiCompatShim. 請使用 2.1 相容性版本 (.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)) 以繼續使用相容性填充碼。Use the 2.1 compatibility version (.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)) to continue using the compatibility shim.

  • 端點路由與使用傳統路由時所產生 URI 大小寫的行為不同。Endpoint Routing has different behavior for the casing of generated URIs when using conventional routes.

    請考慮下列預設路由範本:Consider the following default route template:

    app.UseMvc(routes =>
    {
        routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
    

    假設您使用下列路由來產生動作連結:Suppose you generate a link to an action using the following route:

    var link = Url.Action("ReadPost", "blog", new { id = 17, });
    

    使用以 IRouter 為基礎的路由,此程式碼會產生 /blog/ReadPost/17 的 URI,其遵守所提供路由值的大小寫。With IRouter-based routing, this code generates a URI of /blog/ReadPost/17, which respects the casing of the provided route value. ASP.NET Core 2.2 或更新版本中的端點路由會產生 /Blog/ReadPost/17 ("Blog" 為大寫)。Endpoint routing in ASP.NET Core 2.2 or later produces /Blog/ReadPost/17 ("Blog" is capitalized). 端點路由提供 IOutboundParameterTransformer 介面,可用來全域自訂此行為,或為對應 URL 套用不同的慣例。Endpoint routing provides the IOutboundParameterTransformer interface that can be used to customize this behavior globally or to apply different conventions for mapping URLs.

    如需詳細資訊,請參閱參數轉換器參考一節。For more information, see the Parameter transformer reference section.

  • 當嘗試連結至不存在的控制器/動作或頁面時,MVC/Razor Pages 所使用的連結產生與傳統路由的行為不同。Link Generation used by MVC/Razor Pages with conventional routes behaves differently when attempting to link to an controller/action or page that doesn't exist.

    請考慮下列預設路由範本:Consider the following default route template:

    app.UseMvc(routes =>
    {
        routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
    });
    

    假設您使用預設範本和下列程式碼來產生動作連結:Suppose you generate a link to an action using the default template with the following:

    var link = Url.Action("ReadPost", "Blog", new { id = 17, });
    

    使用以 IRouter 為基礎的路由,結果一律為 /Blog/ReadPost/17,即使 BlogController 不存在或沒有 ReadPost 動作方法也一樣。With IRouter-based routing, the result is always /Blog/ReadPost/17, even if the BlogController doesn't exist or doesn't have a ReadPost action method. 如預期,如果動作方法存在,則 ASP.NET Core 2.2 或更新版本中的端點路由會產生 /Blog/ReadPost/17As expected, endpoint routing in ASP.NET Core 2.2 or later produces /Blog/ReadPost/17 if the action method exists. 不過,如果動作不存在,則端點路由會產生空字串。 However, endpoint routing produces an empty string if the action doesn't exist. 就概念而言,如果動作不存在,則端點路由不會假設端點存在。Conceptually, endpoint routing doesn't assume that the endpoint exists if the action doesn't exist.

  • 連結產生「環境值失效演算法」 在搭配端點路由使用時會有不同的行為。The link generation ambient value invalidation algorithm behaves differently when used with endpoint routing.

    「環境值失效」 是一種演算法,會從目前執行的要求 (環境值) 決定可用於連結產生作業的路由值。Ambient value invalidation is the algorithm that decides which route values from the currently executing request (the ambient values) can be used in link generation operations. 傳統路由一律會在連結至其他動作時,使額外的路由值失效。Conventional routing always invalidated extra route values when linking to a different action. 在 ASP.NET Core 2.2 版以前,屬性路由沒有此行為。Attribute routing didn't have this behavior prior to the release of ASP.NET Core 2.2. 在舊版的 ASP.NET Core 中,連結至使用相同路由參數名稱的其他動作會導致連結產生錯誤。In earlier versions of ASP.NET Core, links to another action that use the same route parameter names resulted in link generation errors. 在 ASP.NET Core 2.2 或更新版本中,這兩種路由形式都會在連結至其他動作時使值失效。In ASP.NET Core 2.2 or later, both forms of routing invalidate values when linking to another action.

    請考慮 ASP.NET Core 2.1 或更舊版本中的下列範例。Consider the following example in ASP.NET Core 2.1 or earlier. 連結至其他動作 (或其他頁面) 時,路由值可能會不適當地重複使用。When linking to another action (or another page), route values can be reused in undesirable ways.

    /Pages/Store/Product.cshtml 中:In /Pages/Store/Product.cshtml:

    @page "{id}"
    @Url.Page("/Login")
    

    /Pages/Login.cshtml 中:In /Pages/Login.cshtml:

    @page "{id?}"
    

    如果 URI 在 ASP.NET Core 2.1 或更舊版本中為 /Store/Product/18,則 @Url.Page("/Login") 在 Store/Info 頁面中產生的連結為 /Login/18If the URI is /Store/Product/18 in ASP.NET Core 2.1 or earlier, the link generated on the Store/Info page by @Url.Page("/Login") is /Login/18. 這會重複使用 id 值 18,即使連結目的地是完全不同的應用程式組件也一樣。The id value of 18 is reused, even though the link destination is different part of the app entirely. /Login 頁面內容中的 id 路由值可能是使用者識別碼值,而不是市集產品識別碼值。The id route value in the context of the /Login page is probably a user ID value, not a store product ID value.

    在 ASP.NET Core 2.2 或更新版本中的端點路由中,結果為 /LoginIn endpoint routing with ASP.NET Core 2.2 or later, the result is /Login. 當連結的目的地是不同的動作或頁面時,不會重複使用環境值。Ambient values aren't reused when the linked destination is a different action or page.

  • 往返路由參數語法:使用雙星號 (**) catch-all 參數語法時,斜線不會經過編碼。Round-tripping route parameter syntax: Forward slashes aren't encoded when using a double-asterisk (**) catch-all parameter syntax.

    在連結產生期間,除了斜線,路由系統還會對雙星號 (**) catch-all 參數 (例如 {**myparametername}) 中擷取的值進行編碼。During link generation, the routing system encodes the value captured in a double-asterisk (**) catch-all parameter (for example, {**myparametername}) except the forward slashes. ASP.NET Core 2.2 或更新版本中以 IRouter 為基礎的路由支援雙星號 catch-all。The double-asterisk catch-all is supported with IRouter-based routing in ASP.NET Core 2.2 or later.

    舊版 ASP.NET Core 中的單一星號 catch-all ({*myparametername}) 參數語法仍會受到支援,而且斜線會經過編碼。The single asterisk catch-all parameter syntax in prior versions of ASP.NET Core ({*myparametername}) remains supported, and forward slashes are encoded.

    路由Route 以下列項目產生的連結:Link generated with
    Url.Action(new { category = "admin/products" })
    /search/{*page} /search/admin%2Fproducts (斜線會經過編碼)/search/admin%2Fproducts (the forward slash is encoded)
    /search/{**page} /search/admin/products

中介軟體範例Middleware example

在下列範例中,中介軟體使用 LinkGenerator API 建立列出市集產品的動作方法連結。In the following example, a middleware uses the LinkGenerator API to create link to an action method that lists store products. 應用程式中的任何類別都可以使用連結產生器,方法是將它插入類別並呼叫 GenerateLinkUsing the link generator by injecting it into a class and calling GenerateLink is available to any class in an app.

using Microsoft.AspNetCore.Routing;

public class ProductsLinkMiddleware
{
    private readonly LinkGenerator _linkGenerator;

    public ProductsLinkMiddleware(RequestDelegate next, LinkGenerator linkGenerator)
    {
        _linkGenerator = linkGenerator;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        var url = _linkGenerator.GetPathByAction("ListProducts", "Store");

        httpContext.Response.ContentType = "text/plain";

        await httpContext.Response.WriteAsync($"Go to {url} to see our products.");
    }
}

URL 產生是路由可用來依據一組路由值建立 URL 路徑的處理序。URL generation is the process by which routing can create a URL path based on a set of route values. 這可讓您在路由處理常式和存取它們的 URL 之間建立邏輯分隔。This allows for a logical separation between route handlers and the URLs that access them.

URL 產生遵循類似的反覆執行處理序,但開頭是呼叫路由集合 GetVirtualPath 方法的使用者或架構程式碼。URL generation follows a similar iterative process, but it starts with user or framework code calling into the GetVirtualPath method of the route collection. 每個「路由」 會依序呼叫其 GetVirtualPath 方法,直到傳回非 Null 的 VirtualPathData 為止。Each route has its GetVirtualPath method called in sequence until a non-null VirtualPathData is returned.

GetVirtualPath 的主要輸入是:The primary inputs to GetVirtualPath are:

路由主要使用 ValuesAmbientValues 所提供的路由值,以決定是否可能產生 URL,以及要包含哪些值。Routes primarily use the route values provided by Values and AmbientValues to decide whether it's possible to generate a URL and what values to include. AmbientValues 是比對目前要求所產生的路由值集合。The AmbientValues are the set of route values that were produced from matching the current request. 相反地,Values 是指定如何產生目前作業所需之 URL 的路由值。In contrast, Values are the route values that specify how to generate the desired URL for the current operation. 提供了 HttpContext,以防路由應該取得服務或與目前內容建立關聯的其他資料。The HttpContext is provided in case a route should obtain services or additional data associated with the current context.

提示

VirtualPathContext.Values 視為 VirtualPathContext.AmbientValues 的覆寫項目集合。Think of VirtualPathContext.Values as a set of overrides for the VirtualPathContext.AmbientValues. URL 產生會嘗試重複使用來自目前要求的路由值,讓您使用相同路由或路由值產生連結的 URL。URL generation attempts to reuse route values from the current request to generate URLs for links using the same route or route values.

GetVirtualPath 的輸出是 VirtualPathDataThe output of GetVirtualPath is a VirtualPathData. VirtualPathDataRouteData 的平行處理。VirtualPathData is a parallel of RouteData. VirtualPathData 包含用於輸出 URL 的 VirtualPath,以及一些路由應該設定的其他屬性。VirtualPathData contains the VirtualPath for the output URL and some additional properties that should be set by the route.

VirtualPathData.VirtualPath 屬性包含路由所產生的「虛擬路徑」 。The VirtualPathData.VirtualPath property contains the virtual path produced by the route. 視您需求的不同,可能需要進一步處理路徑。Depending on your needs, you may need to process the path further. 如果您想要以 HTML 呈現產生的 URL,請在前面加上應用程式的基底路徑。If you want to render the generated URL in HTML, prepend the base path of the app.

VirtualPathData.Router 是成功產生 URL 的路由參考。The VirtualPathData.Router is a reference to the route that successfully generated the URL.

VirtualPathData.DataTokens 屬性是其他資料的字典,而這些資料與產生 URL 的路由相關。The VirtualPathData.DataTokens properties is a dictionary of additional data related to the route that generated the URL. 這是 RouteData.DataTokens 的平行處理。This is the parallel of RouteData.DataTokens.

建立路由Create routes

路由提供 Route 類別作為 IRouter 的標準實作。Routing provides the Route class as the standard implementation of IRouter. 在呼叫 RouteAsync 時,Route 會使用「路由範本」 語法來定義將比對 URL 路徑的模式。Route uses the route template syntax to define patterns to match against the URL path when RouteAsync is called. 在呼叫 GetVirtualPath 時,Route 會使用相同的路由範本來產生 URL。Route uses the same route template to generate a URL when GetVirtualPath is called.

大部分的應用程式會藉由呼叫 MapRoute 或其中一個 IRouteBuilder 上定義的類似擴充方法來定建立路由。Most apps create routes by calling MapRoute or one of the similar extension methods defined on IRouteBuilder. 任何 IRouteBuilder 擴充方法都會建立 Route 的執行個體,並將它新增至路由集合。Any of the IRouteBuilder extension methods create an instance of Route and add it to the route collection.

MapRoute 不接受路由處理常式參數。MapRoute doesn't accept a route handler parameter. MapRoute 只會新增 DefaultHandler 所處理的路由。MapRoute only adds routes that are handled by the DefaultHandler. 若要深入了解 MVC 中的路由功能,請參閱 ASP.NET Core 中的路由至控制器動作To learn more about routing in MVC, see ASP.NET Core 中的路由至控制器動作.

MapRoute 不接受路由處理常式參數。MapRoute doesn't accept a route handler parameter. MapRoute 只會新增 DefaultHandler 所處理的路由。MapRoute only adds routes that are handled by the DefaultHandler. 預設處理常式為 IRouter,該處理常式可能無法處理要求。The default handler is an IRouter, and the handler might not handle the request. 例如,ASP.NET Core MVC 通常會設定為預設處理常式,只處理符合可用控制器和動作的要求。For example, ASP.NET Core MVC is typically configured as a default handler that only handles requests that match an available controller and action. 若要深入了解 MVC 中的路由功能,請參閱 ASP.NET Core 中的路由至控制器動作To learn more about routing in MVC, see ASP.NET Core 中的路由至控制器動作.

下列程式碼範例是典型 ASP.NET Core MVC 路由定義所使用的 MapRoute 呼叫範例:The following code example is an example of a MapRoute call used by a typical ASP.NET Core MVC route definition:

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

此範本會比對 URL 路徑,並擷取路由值。This template matches a URL path and extracts the route values. 例如,路徑 /Products/Details/17 會產生下列路由值:{ controller = Products, action = Details, id = 17 }For example, the path /Products/Details/17 generates the following route values: { controller = Products, action = Details, id = 17 }.

路由值是透過將 URL 路徑分割成區段,並比對每個區段與路由範本中的「路由參數」 名稱來判定。Route values are determined by splitting the URL path into segments and matching each segment with the route parameter name in the route template. 路由參數為具名。Route parameters are named. 參數是透過以括弧 { ... } 括住參數名稱來定義。The parameters defined by enclosing the parameter name in braces { ... }.

上述範本也可以比對 URL 路徑 / 並產生值 { controller = Home, action = Index }The preceding template could also match the URL path / and produce the values { controller = Home, action = Index }. 發生這種情況是因為 {controller}{action} 路由參數有預設值,而 id 路由參數為選擇性參數。This occurs because the {controller} and {action} route parameters have default values and the id route parameter is optional. 路由參數名稱之後緊接著值的等號 (=) 會定義參數預設值。An equals sign (=) followed by a value after the route parameter name defines a default value for the parameter. 路由參數名稱之後的問號 (?) 會定義選擇性參數。A question mark (?) after the route parameter name defines an optional parameter.

在路由相符時,具有預設值的路由參數一定 會產生路由值。Route parameters with a default value always produce a route value when the route matches. 如果沒有任何對應的 URL 路徑區段,選擇性參數不會產生路由值。Optional parameters don't produce a route value if there was no corresponding URL path segment. 如需路由範本情節和語法的詳細描述,請參閱路由範本參考一節。See the Route template reference section for a thorough description of route template scenarios and syntax.

在下列範例中,路由參數定義 {id:int} 會定義 id 路由參數的路由條件約束In the following example, the route parameter definition {id:int} defines a route constraint for the id route parameter:

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

此範本會符合 /Products/Details/17 等 URL 路徑,但不符合 /Products/Details/ApplesThis template matches a URL path like /Products/Details/17 but not /Products/Details/Apples. 路由條件約束會實作 IRouteConstraint,並檢查路由值以進行驗證。Route constraints implement IRouteConstraint and inspect route values to verify them. 在此範例中,路由值 id 必須可以轉換為整數。In this example, the route value id must be convertible to an integer. 如需架構所提供之路由條件約束的說明,請參閱路由條件約束參考See route-constraint-reference for an explanation of route constraints provided by the framework.

MapRoute 的其他多載接受 constraintsdataTokensdefaults 的值。Additional overloads of MapRoute accept values for constraints, dataTokens, and defaults. 這些參數通常是用來傳遞匿名類型的物件,其中匿名類型的屬性名稱符合路由參數名稱。The typical usage of these parameters is to pass an anonymously typed object, where the property names of the anonymous type match route parameter names.

下列 MapRoute 範例會建立對等的路由:The following MapRoute examples create equivalent routes:

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

提示

對於簡單的路由而言,定義條件約束和預設的內嵌語法可能很方便。The inline syntax for defining constraints and defaults can be convenient for simple routes. 不過,內嵌語法不支援某些情節 (例如資料語彙基元)。However, there are scenarios, such as data tokens, that aren't supported by inline syntax.

下列範例將示範一些其他情節:The following example demonstrates a few additional scenarios:

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

上述範本會比對 /Blog/All-About-Routing/Introduction 等 URL 路徑,並擷取值 { controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }The preceding template matches a URL path like /Blog/All-About-Routing/Introduction and extracts the values { controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }. 即使範本中沒有任何對應的路由參數,路由也會產生 controlleraction 的預設路由值。The default route values for controller and action are produced by the route even though there are no corresponding route parameters in the template. 預設值可以在路由範本中指定。Default values can be specified in the route template. article 路由參數透過在路由參數名稱之前加上雙星號 (**) 來定義為 catch-allThe article route parameter is defined as a catch-all by the appearance of an double asterisk (**) before the route parameter name. 全部擷取路由參數會擷取 URL 路徑的其餘部分,而且也可以符合空字串。Catch-all route parameters capture the remainder of the URL path and can also match the empty string.

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

上述範本會比對 /Blog/All-About-Routing/Introduction 等 URL 路徑,並擷取值 { controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }The preceding template matches a URL path like /Blog/All-About-Routing/Introduction and extracts the values { controller = Blog, action = ReadArticle, article = All-About-Routing/Introduction }. 即使範本中沒有任何對應的路由參數,路由也會產生 controlleraction 的預設路由值。The default route values for controller and action are produced by the route even though there are no corresponding route parameters in the template. 預設值可以在路由範本中指定。Default values can be specified in the route template. article 路由參數透過在路由參數名稱之前加上一個星號 (*) 來定義為 catch-allThe article route parameter is defined as a catch-all by the appearance of an asterisk (*) before the route parameter name. 全部擷取路由參數會擷取 URL 路徑的其餘部分,而且也可以符合空字串。Catch-all route parameters capture the remainder of the URL path and can also match the empty string.

下列範例會新增路由條件約束和資料語彙基元:The following example adds route constraints and data tokens:

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 路徑,並擷取值 { controller = Products, action = Details, id = 5 } 和資料語彙基元 { locale = en-US }The preceding template matches a URL path like /en-US/Products/5 and extracts the values { controller = Products, action = Details, id = 5 } and the data tokens { locale = en-US }.

[區域變數] 視窗語彙基元

路由類別 URL 產生Route class URL generation

Route 類別也可以結合一組路由值與其路由範本來產生 URL。The Route class can also perform URL generation by combining a set of route values with its route template. 這在邏輯上是比對 URL 路徑的反向處理序。This is logically the reverse process of matching the URL path.

提示

若要進一步了解 URL 產生,請假設您想要產生的 URL,並考慮路由範本將會如何比對該 URL。To better understand URL generation, imagine what URL you want to generate and then think about how a route template would match that URL. 產生的值為何?What values would be produced? 這與 URL 產生在 Route 類別中的運作方式大致相同。This is the rough equivalent of how URL generation works in the Route class.

下列範例使用一般 ASP.NET Core MVC 預設路由:The following example uses a general ASP.NET Core MVC default route:

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

路由值為 { controller = Products, action = List } 時,會產生 URL /Products/ListWith the route values { controller = Products, action = List }, the URL /Products/List is generated. 路由值會取代對應的路由參數,以形成 URL 路徑。The route values are substituted for the corresponding route parameters to form the URL path. 由於 id 是選擇性路由參數,因此沒有 id 值也可以成功產生 URL。Since id is an optional route parameter, the URL is successfully generated without a value for id.

路由值為 { controller = Home, action = Index } 時,會產生 URL /With the route values { controller = Home, action = Index }, the URL / is generated. 所提供的路由值符合預設值,因此可以放心地省略這些預設值對應的區段。The provided route values match the default values, and the segments corresponding to the default values are safely omitted.

這兩個產生的 URL 會使用下列路由定義 (/Home/Index/) 反覆存取,並產生用來產生 URL 的相同路由值。Both URLs generated round-trip with the following route definition (/Home/Index and /) produce the same route values that were used to generate the URL.

注意

使用 ASP.NET Core MVC 的應用程式應該使用 UrlHelper 來產生 URL,而不是直接呼叫路由。An app using ASP.NET Core MVC should use UrlHelper to generate URLs instead of calling into routing directly.

如需 URL 產生的詳細資訊,請參閱 URI 產生參考一節。For more information on URL generation, see the Url generation reference section.

使用路由中介軟體Use Routing Middleware

參考應用程式專案檔中的 Microsoft.AspNetCore.App 中繼套件Reference the Microsoft.AspNetCore.App metapackage in the app's project file.

Startup.ConfigureServices 中,將路由新增至服務容器:Add routing to the service container in Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRouting();
}

路由必須設定在 Startup.Configure 方法中。Routes must be configured in the Startup.Configure method. 範例應用程式使用下列 API:The sample app uses the following APIs:

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$)}/{id:int}");

routeBuilder.MapGet("hello/{name}", context =>
{
    var name = context.GetRouteValue("name");
    // The route handler 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);

下表顯示使用指定 URL 的回應。The following table shows the responses with the given URIs.

URIURI 回應Response
/package/create/3 Hello!Hello! Route values: [operation, create], [id, 3]Route values: [operation, create], [id, 3]
/package/track/-3 Hello!Hello! Route values: [operation, track], [id, -3]Route values: [operation, track], [id, -3]
/package/track/-3/ Hello!Hello! Route values: [operation, track], [id, -3]Route values: [operation, track], [id, -3]
/package/track/ 要求失敗,沒有相符項目。The request falls through, no match.
GET /hello/Joe Hi, Joe!Hi, Joe!
POST /hello/Joe 要求失敗,僅符合 HTTP GET。The request falls through, matches HTTP GET only.
GET /hello/Joe/Smith 要求失敗,沒有相符項目。The request falls through, no match.

如果您要設定單一路由,請呼叫傳入 IRouter 執行個體的 UseRouterIf you're configuring a single route, call UseRouter passing in an IRouter instance. 您不需要使用 RouteBuilderYou won't need to use RouteBuilder.

架構會提供一組擴充方法來建立路由 (RequestDelegateRouteBuilderExtensions):The framework provides a set of extension methods for creating routes (RequestDelegateRouteBuilderExtensions):

其中一些列出的方法 (例如 MapGet) 需要 RequestDelegateSome of listed methods, such as MapGet, require a RequestDelegate. 路由相符時,RequestDelegate 會作為「路由處理常式」 使用。The RequestDelegate is used as the route handler when the route matches. 此系列中的其他方法允許設定中介軟體管線,以作為路由處理常式使用。Other methods in this family allow configuring a middleware pipeline for use as the route handler. 如果 Map* 方法不接受處理常式 (例如 MapRoute),則會使用 DefaultHandlerIf the Map* method doesn't accept a handler, such as MapRoute, it uses the DefaultHandler.

Map[Verb] 方法會使用條件約束,將路由限制為方法名稱中的 HTTP 指令動詞。The Map[Verb] methods use constraints to limit the route to the HTTP Verb in the method name. 如需範例,請參閱 MapGetMapVerbFor example, see MapGet and MapVerb.

路由範本參考Route template reference

大括弧 ({ ... }) 內的語彙基元定義路由相符時會繫結的「路由參數」 。Tokens within curly braces ({ ... }) define route parameters that are bound if the route is matched. 您可以在路由區段中定義多個路由參數,但其必須以常值分隔。You can define more than one route parameter in a route segment, but they must be separated by a literal value. 例如,{controller=Home}{action=Index} 不是有效的路由,因為 {controller}{action} 之間沒有任何常值。For example, {controller=Home}{action=Index} isn't a valid route, since there's no literal value between {controller} and {action}. 這些路由參數必須有一個名稱,並且可以指定其他屬性。These route parameters must have a name and may have additional attributes specified.

路由參數之外的常值文字 (例如,{id}) 和路徑分隔符號 / 必須符合 URL 中的文字。Literal text other than route parameters (for example, {id}) and the path separator / must match the text in the URL. 文字比對會區分大小寫,並以 URL 路徑的已解碼表示法為基礎。Text matching is case-insensitive and based on the decoded representation of the URLs path. 若要比對常值路由參數分隔符號 ({}),請重複字元 ({{}}) 來將分隔符號逸出。To match a literal route parameter delimiter ({ or }), escape the delimiter by repeating the character ({{ or }}).

URL 模式嘗試擷取具有選擇性副檔名的檔案名稱時,具有其他考量。URL patterns that attempt to capture a file name with an optional file extension have additional considerations. 以範本 files/{filename}.{ext?} 為例。For example, consider the template files/{filename}.{ext?}. filenameext 都存在值時,就會填入這兩個值。When values for both filename and ext exist, both values are populated. 如果 URL 中只有 filename 存在值,由於結尾的句點 (.) 是選擇性項目,因此路由相符。If only a value for filename exists in the URL, the route matches because the trailing period (.) is optional. 下列 URL 符合此路由:The following URLs match this route:

  • /files/myFile.txt
  • /files/myFile

您可以使用一個星號 (*) 或雙星號 (**) 作為路由參數的前置詞,以繫結至 URI 的其餘部分。You can use an asterisk (*) or double asterisk (**) as a prefix to a route parameter to bind to the rest of the URI. 這稱為 catch-all 參數。These are called a catch-all parameters. 例如,blog/{**slug} 符合以 /blog 開頭且其後有任何值 (這會指派給 slug 路由值) 的所有 URI。For example, blog/{**slug} matches any URI that starts with /blog and has any value following it, which is assigned to the slug route value. 全部擷取參數也可以符合空字串。Catch-all parameters can also match the empty string.

當使用路由產生 URL (包括路徑分隔符號 (/) 字元) 時,catch-all 參數會逸出適當的字元。The catch-all parameter escapes the appropriate characters when the route is used to generate a URL, including path separator (/) characters. 例如,路由值為 { path = "my/path" } 的路由 foo/{*path} 會產生 foo/my%2FpathFor example, the route foo/{*path} with route values { path = "my/path" } generates foo/my%2Fpath. 請注意逸出的斜線。Note the escaped forward slash. 若要反覆存取路徑分隔符號字元,請使用 ** 路由參數前置詞。To round-trip path separator characters, use the ** route parameter prefix. 具有 { path = "my/path" } 的路由 foo/{**path} 會產生 foo/my/pathThe route foo/{**path} with { path = "my/path" } generates foo/my/path.

您可以使用星號 (*) 作為路由參數的前置詞,以繫結至 URI 的其餘部分。You can use the asterisk (*) as a prefix to a route parameter to bind to the rest of the URI. 這稱為「全部擷取」 參數。This is called a catch-all parameter. 例如,blog/{*slug} 符合以 /blog 開頭且其後有任何值 (這會指派給 slug 路由值) 的所有 URI。For example, blog/{*slug} matches any URI that starts with /blog and has any value following it, which is assigned to the slug route value. 全部擷取參數也可以符合空字串。Catch-all parameters can also match the empty string.

當使用路由產生 URL (包括路徑分隔符號 (/) 字元) 時,catch-all 參數會逸出適當的字元。The catch-all parameter escapes the appropriate characters when the route is used to generate a URL, including path separator (/) characters. 例如,路由值為 { path = "my/path" } 的路由 foo/{*path} 會產生 foo/my%2FpathFor example, the route foo/{*path} with route values { path = "my/path" } generates foo/my%2Fpath. 請注意逸出的斜線。Note the escaped forward slash.

路由參數可能有「預設值」 ,指定方法是在參數名稱之後指定預設值,並以等號 (=) 分隔。Route parameters may have default values designated by specifying the default value after the parameter name separated by an equals sign (=). 例如,{controller=Home} 定義 Home 作為 controller 的預設值。For example, {controller=Home} defines Home as the default value for controller. 如果 URL 中沒有用於參數的任何值,則會使用預設值。The default value is used if no value is present in the URL for the parameter. 路由參數也可以設為選擇性,方法是在參數名稱結尾附加問號 (?),如 id? 中所示。Route parameters are made optional by appending a question mark (?) to the end of the parameter name, as in id?. 選擇性值與預設路由參數之間的差異在於,具有預設值的路由參數一定會產生值—選擇性參數只有在要求 URL 提供值時才會有值。The difference between optional values and default route parameters is that a route parameter with a default value always produces a value—an optional parameter has a value only when a value is provided by the request URL.

路由參數可能具有條件約束,這些條件約束必須符合與 URL 繫結的路由值。Route parameters may have constraints that must match the route value bound from the URL. 在路由參數名稱之後新增分號 (:) 和條件約束名稱,即可指定路由參數的「內嵌條件約束」 。Adding a colon (:) and constraint name after the route parameter name specifies an inline constraint on a route parameter. 如果條件約束需要引數,這些引數會在條件約束名稱後面以括弧 ((...)) 括住。If the constraint requires arguments, they're enclosed in parentheses ((...)) after the constraint name. 指定多個內嵌條件約束的方法是附加另一個冒號 (:) 和條件約束名稱。Multiple inline constraints can be specified by appending another colon (:) and constraint name.

條件約束名稱和引述會傳遞至 IInlineConstraintResolver 服務來建立 IRouteConstraint 的執行個體,以用於 URL 處理。The constraint name and arguments are passed to the IInlineConstraintResolver service to create an instance of IRouteConstraint to use in URL processing. 例如,路由範本 blog/{article:minlength(10)} 指定具有引數 10minlength 條件約束。For example, the route template blog/{article:minlength(10)} specifies a minlength constraint with the argument 10. 如需路由條件約束詳細資訊和架構所提供的條件約束清單,請參閱路由條件約束參考一節。For more information on route constraints and a list of the constraints provided by the framework, see the Route constraint reference section.

路由參數也可以具有參數轉換器,以在產生連結及根據 URL 比對動作和頁面時,轉換參數的值。Route parameters may also have parameter transformers, which transform a parameter's value when generating links and matching actions and pages to URLs. 與條件約束類似,可以透過在路徑參數名稱後面新增冒號 (:) 和轉換器名稱,將參數轉換器內嵌新增至路徑參數。Like constraints, parameter transformers can be added inline to a route parameter by adding a colon (:) and transformer name after the route parameter name. 例如,路由範本 blog/{article:slugify} 會指定 slugify 轉換器。For example, the route template blog/{article:slugify} specifies a slugify transformer. 如需參數轉換器的詳細資訊,請參閱參數轉器參考一節。For more information on parameter transformers, see the Parameter transformer reference section.

下表示範範例路由範本及其行為。The following table demonstrates example route templates and their behavior.

路由範本Route Template 範例比對 URIExample Matching URI 要求 URI…The request URI…
hello /hello 只比對單一路徑 /helloOnly matches the single path /hello.
{Page=Home} / 比對並將 Page 設定為 HomeMatches and sets Page to Home.
{Page=Home} /Contact 比對並將 Page 設定為 ContactMatches and sets Page to Contact.
{controller}/{action}/{id?} /Products/List 對應至 Products 控制器和 List 動作。Maps to the Products controller and List action.
{controller}/{action}/{id?} /Products/Details/123 對應至 Products 控制器和 Details 動作 (id 設定為 123)。Maps to the Products controller and Details action (id set to 123).
{controller=Home}/{action=Index}/{id?} / 對應至 Home 控制器和 Index 方法 (會忽略 id)。Maps to the Home controller and Index method (id is ignored).

使用範本通常是最簡單的路由方式。Using a template is generally the simplest approach to routing. 條件約束和預設值也可以在路由範本外部指定。Constraints and defaults can also be specified outside the route template.

提示

啟用記錄以查看內建路由實作 (例如 Route) 如何符合要求。Enable Logging to see how the built-in routing implementations, such as Route, match requests.

保留的路由名稱Reserved routing names

下列關鍵字是保留的名稱,不能用作路由名稱或參數:The following keywords are reserved names and can't be used as route names or parameters:

  • action
  • area
  • controller
  • handler
  • page

路由條件約束參考Route constraint reference

路由條件約束執行時機是出現符合傳入 URL 的項目,並將 URL 路徑語彙基元化成路由值時。Route constraints execute when a match has occurred to the incoming URL and the URL path is tokenized into route values. 路由條件約束通常會透過路由範本檢查相關聯的路由值,並對是否可接受值做出是/否決策。Route constraints generally inspect the route value associated via the route template and make a yes/no decision about whether or not the value is acceptable. 某些路由條件約束會使用路由值以外的資料,以考慮是否可以路由要求。Some route constraints use data outside the route value to consider whether the request can be routed. 例如,HttpMethodRouteConstraint 可以依據其 HTTP 指令動詞接受或拒絕要求。For example, the HttpMethodRouteConstraint can accept or reject a request based on its HTTP verb. 條件約束可用於路由要求和連結產生。Constraints are used in routing requests and link generation.

警告

請勿針對輸入驗證使用條件約束。Don't use constraints for input validation. 如果針對輸入驗證使用條件約束,則無效的輸入會導致產生「404 - 找不到」 回應,而不是「400 - 錯誤要求」 與適當的錯誤訊息。If constraints are used for input validation, invalid input results in a 404 - Not Found response instead of a 400 - Bad Request with an appropriate error message. 路由條件約束會用來釐清類似的路由,而不是用來驗證特定路由的輸入。Route constraints are used to disambiguate similar routes, not to validate the inputs for a particular route.

下表示範範例路由條件約束及其預期行為。The following table demonstrates example route constraints and their expected behavior.

條件約束constraint 範例Example 範例相符項目Example Matches 注意Notes
int {id:int} 123456789-123456789123456789, -123456789 符合任何整數Matches any integer
bool {active:bool} trueFALSEtrue, FALSE 符合 truefalse (不區分大小寫)Matches true or false (case-insensitive)
datetime {dob:datetime} 2016-12-312016-12-31 7:32pm2016-12-31, 2016-12-31 7:32pm 符合有效的 DateTime 值 (在不因國別而異的文化特性中 - 請參閱警告)Matches a valid DateTime value (in the invariant culture - see warning)
decimal {price:decimal} 49.99-1,000.0149.99, -1,000.01 符合有效的 decimal 值 (在不因國別而異的文化特性中 - 請參閱警告)Matches a valid decimal value (in the invariant culture - see warning)
double {weight:double} 1.234-1,001.01e81.234, -1,001.01e8 符合有效的 double 值 (在不因國別而異的文化特性中 - 請參閱警告)Matches a valid double value (in the invariant culture - see warning)
float {weight:float} 1.234-1,001.01e81.234, -1,001.01e8 符合有效的 float 值 (在不因國別而異的文化特性中 - 請參閱警告)Matches a valid float value (in the invariant culture - see warning)
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638{CD2C1638-1638-72D5-1638-DEADBEEF1638}CD2C1638-1638-72D5-1638-DEADBEEF1638, {CD2C1638-1638-72D5-1638-DEADBEEF1638} 符合有效的 GuidMatches a valid Guid value
long {ticks:long} 123456789-123456789123456789, -123456789 符合有效的 longMatches a valid long value
minlength(value) {username:minlength(4)} Rick 字串必須至少有 4 個字元String must be at least 4 characters
maxlength(value) {filename:maxlength(8)} Richard 字串不能超過 8 個字元String must be no more than 8 characters
length(length) {filename:length(12)} somefile.txt 字串長度必須剛好是 12 個字元String must be exactly 12 characters long
length(min,max) {filename:length(8,16)} somefile.txt 字串長度必須至少有 8 個字元,但不能超過 16 個字元String must be at least 8 and no more than 16 characters long
min(value) {age:min(18)} 19 整數值必須至少為 18Integer value must be at least 18
max(value) {age:max(120)} 91 整數值不能超過 120Integer value must be no more than 120
range(min,max) {age:range(18,120)} 91 整數值必須至少為 18,但不能超過 120Integer value must be at least 18 but no more than 120
alpha {name:alpha} Rick 字串必須包含一或多個字母字元 (a-z,不區分大小寫)String must consist of one or more alphabetical characters (a-z, case-insensitive)
regex(expression) {ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)} 123-45-6789 字串必須符合規則運算式 (請參閱有關定義規則運算式的提示)String must match the regular expression (see tips about defining a regular expression)
required {name:required} Rick 用來強制執行在 URL 產生期間呈現非參數值Used to enforce that a non-parameter value is present during URL generation

以冒號分隔的多個條件約束,可以套用至單一參數。Multiple, colon-delimited constraints can be applied to a single parameter. 例如,下列條件約束會將參數限制在 1 或更大的整數值:For example, the following constraint restricts a parameter to an integer value of 1 or greater:

[Route("users/{id:int:min(1)}")]
public User GetUserById(int id) { }

警告

確認 URL 可以轉換成 CLR 類型的路由條件約束 (例如 intDateTime) 一律使用不因國別而異的文化特性。Route constraints that verify the URL and are converted to a CLR type (such as int or DateTime) always use the invariant culture. 這些條件約束假設 URL 不可當地語系化。These constraints assume that the URL is non-localizable. 架構提供的路由條件約束不會修改路由值中儲存的值。The framework-provided route constraints don't modify the values stored in route values. 所有從 URL 剖析而來的路由值會儲存為字串。All route values parsed from the URL are stored as strings. 例如,float 條件約束會嘗試將路由值轉換成浮點數,但轉換的值只能用來確認它可以轉換成浮點數。For example, the float constraint attempts to convert the route value to a float, but the converted value is used only to verify it can be converted to a float.

規則運算式Regular expressions

ASP.NET Core 架構將 RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant 新增至規則運算式建構函式。The ASP.NET Core framework adds RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant to the regular expression constructor. 如需這些成員的說明,請參閱 RegexOptionsSee RegexOptions for a description of these members.

規則運算式使用的分隔符號和語彙基元,類似於路由和 C# 語言所使用的分隔符號和語彙基元。Regular expressions use delimiters and tokens similar to those used by Routing and the C# language. 規則運算式的語彙基元必須逸出。Regular expression tokens must be escaped. 若要在路由中使用規則運算式 ^\d{3}-\d{2}-\d{4}$,運算式必須以字串中所提供的 \ (單一反斜線) 字元作為 C# 原始程式檔中的 \\ (雙反斜線) 字元,才能逸出 \ 字串逸出字元 (除非使用逐字字串常值)。To use the regular expression ^\d{3}-\d{2}-\d{4}$ in routing, the expression must have the \ (single backslash) characters provided in the string as \\ (double backslash) characters in the C# source file in order to escape the \ string escape character (unless using verbatim string literals). 若要逸出路由參數分隔符號字元 ({}[]),請在運算式中使用雙字元 ({{}[[]]).To escape routing parameter delimiter characters ({, }, [, ]), double the characters in the expression ({{, }, [[, ]]). 下表顯示規則運算式和逸出的版本。The following table shows a regular expression and the escaped version.

規則運算式Regular Expression 逸出的規則運算式Escaped Regular Expression
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

路由中所使用的規則運算式通常以插入號 (^) 字元開頭,並符合字串的開始位置。Regular expressions used in routing often start with the caret (^) character and match starting position of the string. 運算式通常以貨幣符號 ($) 字元結尾,並符合字串的結尾。The expressions often end with the dollar sign ($) character and match end of the string. ^$ 字元可確保規則運算式符合整個路由參數值。The ^ and $ characters ensure that the regular expression match the entire route parameter value. 若不使用 ^$ 字元,規則運算式會比對字串內的所有部分字串,這通常不是您想要的結果。Without the ^ and $ characters, the regular expression match any substring within the string, which is often undesirable. 下表提供範例,並說明它們符合或無法符合的原因。The following table provides examples and explains why they match or fail to match.

運算式Expression StringString 比對Match 註解Comment
[a-z]{2} hellohello Yes 子字串相符項目Substring matches
[a-z]{2} 123abc456123abc456 Yes 子字串相符項目Substring matches
[a-z]{2} mzmz Yes 符合運算式Matches expression
[a-z]{2} MZMZ Yes 不區分大小寫Not case sensitive
^[a-z]{2}$ hellohello No 請參閱上述的 ^$See ^ and $ above
^[a-z]{2}$ 123abc456123abc456 No 請參閱上述的 ^$See ^ and $ above

如需規則運算式語法的詳細資訊,請參閱 .NET Framework 規則運算式For more information on regular expression syntax, see .NET Framework Regular Expressions.

若要將參數限制為一組已知的可能值,請使用規則運算式。To constrain a parameter to a known set of possible values, use a regular expression. 例如,{action:regex(^(list|get|create)$)} 只會將 action 路由值與 listgetcreate 相符。For example, {action:regex(^(list|get|create)$)} only matches the action route value to list, get, or create. 如果已傳入條件約束字典,字串 ^(list|get|create)$ 則是對等項目。If passed into the constraints dictionary, the string ^(list|get|create)$ is equivalent. 已傳入條件約束字典 (未內嵌在範本內) 的條件約束,即使不符合其中一個已知的條件約束,也會被視為規則運算式。Constraints that are passed in the constraints dictionary (not inline within a template) that don't match one of the known constraints are also treated as regular expressions.

自訂路由限制式Custom Route Constraints

除了內建的路由限制式之外,自訂路由限制式也可以透過實作 IRouteConstraint 介面來建立。In addition to the built-in route constraints, custom route constraints can be created by implementing the IRouteConstraint interface. IRouteConstraint 介面包含單一方法 Match,此方法會在滿足限制式時傳回 true,否則會傳回 falseThe IRouteConstraint interface contains a single method, Match, which returns true if the constraint is satisfied and false otherwise.

若要使用自訂 IRouteConstraint,路由限制式型別必須必須向應用程式的 ConstraintMap (在應用程式的服務容器中) 註冊。To use a custom IRouteConstraint, the route constraint type must be registered with the app's ConstraintMap in the app's service container. ConstraintMap 是一個目錄,它將路由限制式機碼對應到可驗證那些限制式的 IRouteConstraint 實作。A ConstraintMap is a dictionary that maps route constraint keys to IRouteConstraint implementations that validate those constraints. 更新應用程式的 ConstraintMap 時,可在 Startup.ConfigureServices 中於進行 services.AddRouting 呼叫時更新,或透過使用 services.Configure<RouteOptions> 直接設定 RouteOptions 來更新。An app's ConstraintMap can be updated in Startup.ConfigureServices either as part of a services.AddRouting call or by configuring RouteOptions directly with services.Configure<RouteOptions>. 例如:For example:

services.AddRouting(options =>
{
    options.ConstraintMap.Add("customName", typeof(MyCustomConstraint));
});

限制式接著能以一般方式套用到路由 (使用註冊限制式型別時使用名稱)。The constraint can then be applied to routes in the usual manner, using the name specified when registering the constraint type. 例如:For example:

[HttpGet("{id:customName}")]
public ActionResult<string> Get(string id)

參數轉換器參考Parameter transformer reference

參數轉換程式:Parameter transformers:

  • 會在為 Route 產生連結時執行。Execute when generating a link for a Route.
  • 實作 Microsoft.AspNetCore.Routing.IOutboundParameterTransformerImplement Microsoft.AspNetCore.Routing.IOutboundParameterTransformer.
  • 是使用 ConstraintMap 進行設定的。Are configured using ConstraintMap.
  • 採用參數的路由值,並將它轉換為新的字串值。Take the parameter's route value and transform it to a new string value.
  • 導致在所產生連結中使用已轉換的值。Result in using the transformed value in the generated link.

例如,具有 Url.Action(new { article = "MyTestArticle" }) 之路由模式 blog\{article:slugify} 中的自訂 slugify 參數轉換器,會產生 blog\my-test-articleFor example, a custom slugify parameter transformer in route pattern blog\{article:slugify} with Url.Action(new { article = "MyTestArticle" }) generates blog\my-test-article.

若要在路由模式中使用參數轉換器,請先在 Startup.ConfigureServices 中使用 ConstraintMap 進行設定:To use a parameter transformer in a route pattern, configure it first using ConstraintMap in Startup.ConfigureServices:

services.AddRouting(options =>
{
    // Replace the type and the name used to refer to it with your own
    // IOutboundParameterTransformer implementation
    options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
});

架構會使用參數轉換器來轉換端點解析的 URI。Parameter transformers are used by the framework to transform the URI where an endpoint resolves. 例如,ASP.NET Core MVC 會使用參數轉換器,轉換用於比對 areacontrolleractionpage 的路由值。For example, ASP.NET Core MVC uses parameter transformers to transform the route value used to match an area, controller, action, and page.

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

使用上述的路由,動作 SubscriptionManagementController.GetAll() 會與URI /subscription-management/get-all 比對。With the preceding route, the action SubscriptionManagementController.GetAll() is matched with the URI /subscription-management/get-all. 參數轉換器不會變更用來產生連結的路由值。A parameter transformer doesn't change the route values used to generate a link. 例如,Url.Action("GetAll", "SubscriptionManagement") 會輸出 /subscription-management/get-allFor example, Url.Action("GetAll", "SubscriptionManagement") outputs /subscription-management/get-all.

ASP.NET Core 針對搭配產生的路由使用參數轉換程式提供了 API 慣例:ASP.NET Core provides API conventions for using a parameter transformers with generated routes:

  • ASP.NET Core MVC 有 Microsoft.AspNetCore.Mvc.ApplicationModels.RouteTokenTransformerConvention API 慣例。ASP.NET Core MVC has the Microsoft.AspNetCore.Mvc.ApplicationModels.RouteTokenTransformerConvention API convention. 此慣例會將所指定參數轉換程式套用到應用程式中的所有屬性路由。This convention applies a specified parameter transformer to all attribute routes in the app. 參數轉換程式會在被取代時轉換屬性路由語彙基元。The parameter transformer transforms attribute route tokens as they are replaced. 如需詳細資訊,請參閱使用參數轉換程式自訂語彙基元取代For more information, see Use a parameter transformer to customize token replacement.
  • Razor Pages 有 Microsoft.AspNetCore.Mvc.ApplicationModels.PageRouteTransformerConvention API 慣例。Razor Pages has the Microsoft.AspNetCore.Mvc.ApplicationModels.PageRouteTransformerConvention API convention. 此慣例會將所指定參數轉換器套用至所有自動探索到的 Razor Pages。This convention applies a specified parameter transformer to all automatically discovered Razor Pages. 參數轉換器會轉換 Razor Pages 路由的資料夾與檔案名稱區段。The parameter transformer transforms the folder and file name segments of Razor Pages routes. 如需詳細資訊,請參閱使用參數轉換程式自訂頁面路由For more information, see Use a parameter transformer to customize page routes.

URL 產生參考URL generation reference

下列範例示範如何在指定路由值字典和 RouteCollection 的情況下產生路由的連結。The following example shows how to generate a link to a route given a dictionary of route values and a RouteCollection.

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/123The VirtualPath generated at the end of the preceding sample is /package/create/123. 字典提供「追蹤套件路由」範本 package/{operation}/{id}operationid 路由值。The dictionary supplies the operation and id route values of the "Track Package Route" template, package/{operation}/{id}. 如需詳細資訊,請參閱使用路由中介軟體一節或範例應用程式中的範例程式碼。For details, see the sample code in the Use Routing Middleware section or the sample app.

VirtualPathContext 建構函式的第二個參數是「環境值」 的集合。The second parameter to the VirtualPathContext constructor is a collection of ambient values. 環境值便於使用,因為它們會限制開發人員必須在要求內容中指定的值數目。Ambient values are convenient to use because they limit the number of values a developer must specify within a request context. 目前要求的目前路由值被視為用於連結產生的環境值。The current route values of the current request are considered ambient values for link generation. 在 ASP.NET Core MVC 應用程式 HomeControllerAbout 動作中,您不需要指定控制器路由值以連結到 Index 動作—會使用 Home 的環境值。In an ASP.NET Core MVC app's About action of the HomeController, you don't need to specify the controller route value to link to the Index action—the ambient value of Home is used.

不符合參數的環境值會予以忽略。Ambient values that don't match a parameter are ignored. 當明確提供的值覆寫環境值時,也會忽略環境值。Ambient values are also ignored when an explicitly provided value overrides the ambient value. URL 中的比對是從左到右。Matching occurs from left to right in the URL.

明確提供但不符合路由區段的值會新增至查詢字串。Values explicitly provided but that don't match a segment of the route are added to the query string. 下表顯示使用路由範本 {controller}/{action}/{id?} 時的結果。The following table shows the result when using the route template {controller}/{action}/{id?}.

環境值Ambient Values 明確值Explicit Values 結果Result
controller = "Home"controller = "Home" action = "About"action = "About" /Home/About
controller = "Home"controller = "Home" controller = "Order", action = "About"controller = "Order", action = "About" /Order/About
controller = "Home", color = "Red"controller = "Home", color = "Red" action = "About"action = "About" /Home/About
controller = "Home"controller = "Home" action = "About", color = "Red"action = "About", color = "Red" /Home/About?color=Red

如果路由具有未對應至參數的預設值,且該值會明確提供,它必須符合預設值:If a route has a default value that doesn't correspond to a parameter and that value is explicitly provided, it must match the default value:

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

連結產生只有在提供了 controlleraction 的相符值時,才會產生此路由的連結。Link generation only generates a link for this route when the matching values for controller and action are provided.

複雜區段Complex segments

複雜區段 (例如,[Route("/x{token}y")]) 會透過以非窮盡的方式,由右至左比對常值來處理。Complex segments (for example [Route("/x{token}y")]) are processed by matching up literals from right to left in a non-greedy way. 請參閱此程式碼以了解如何比對複雜區段的詳細解釋。See this code for a detailed explanation of how complex segments are matched. 程式法範例不是由 ASP.NET Core 使用,但它提供一個好的複雜區段解釋。The code sample is not used by ASP.NET Core, but it provides a good explanation of complex segments.