ASP.NET Web API 中的路由Routing in ASP.NET Web API

藉由Mike Wassonby Mike Wasson

這篇文章說明 ASP.NET Web API 將 HTTP 要求路由至控制器的方式。This article describes how ASP.NET Web API routes HTTP requests to controllers.

Note

如果您熟悉 ASP.NET MVC、 Web API 路由是非常類似於 MVC 路由。If you are familiar with ASP.NET MVC, Web API routing is very similar to MVC routing. 主要差異在於,Web API 會使用 HTTP 指令動詞,而不是 URI 路徑,,在選取的動作。The main difference is that Web API uses the HTTP verb, not the URI path, to select the action. 您也可以使用 Web API 中的 MVC 樣式路由。You can also use MVC-style routing in Web API. 這篇文章不採用任何 ASP.NET MVC 的知識。This article does not assume any knowledge of ASP.NET MVC.

路由表Routing Tables

在 ASP.NET Web API 中,控制器是處理 HTTP 要求的類別。In ASP.NET Web API, a controller is a class that handles HTTP requests. 控制站的公用方法會呼叫動作方法簡稱動作The public methods of the controller are called action methods or simply actions. 當 Web API 架構會收到要求時,它會將要求路由至動作。When the Web API framework receives a request, it routes the request to an action.

若要判斷要叫用動作,架構會使用路由表To determine which action to invoke, the framework uses a routing table. Web API 的 Visual Studio 專案範本會建立預設路由:The Visual Studio project template for Web API creates a default route:

routes.MapHttpRoute(
    name: "API Default",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

此路由定義於WebApiConfig.cs檔案,其會置於應用程式_啟動目錄:This route is defined in the WebApiConfig.cs file, which is placed in the App_Start directory:

如需詳細資訊WebApiConfig類別,請參閱設定 ASP.NET Web APIFor more information about the WebApiConfig class, see Configuring ASP.NET Web API.

如果您自我裝載 Web API,您必須直接上設定的路由表HttpSelfHostConfiguration物件。If you self-host Web API, you must set the routing table directly on the HttpSelfHostConfiguration object. 如需詳細資訊,請參閱 < 自我裝載 Web APIFor more information, see Self-Host a Web API.

路由表中的每個項目包含路由範本Each entry in the routing table contains a route template. Web API 的預設路由範本"api / {controller} / {id}"。The default route template for Web API is "api/{controller}/{id}". 此範本中, "api"是常值路徑區段和 {controller} 和 {id} 是預留位置變數。In this template, "api" is a literal path segment, and {controller} and {id} are placeholder variables.

當 Web API 架構會收到 HTTP 要求時,它會嘗試比對針對其中一個路由表中的路由範本的 URI。When the Web API framework receives an HTTP request, it tries to match the URI against one of the route templates in the routing table. 如果沒有路由相符,用戶端會收到 404 錯誤。If no route matches, the client receives a 404 error. 例如,下列 Uri 會符合預設路由:For example, the following URIs match the default route:

  • /api/contacts/api/contacts
  • /api/contacts/1/api/contacts/1
  • /api/products/gizmo1/api/products/gizmo1

不過,下列 URI 不符合,因為它缺少"api"區段:However, the following URI does not match, because it lacks the "api" segment:

  • /contacts/1/contacts/1

Note

使用路由中的 「 api 」 的原因是避免與 ASP.NET MVC routing 發生衝突。The reason for using "api" in the route is to avoid collisions with ASP.NET MVC routing. 如此一來,您可以有"/連絡"移至 MVC 控制器,並"/api/連絡人"移至 Web API 控制器。That way, you can have "/contacts" go to an MVC controller, and "/api/contacts" go to a Web API controller. 當然,如果您不喜歡這個慣例,您可以變更預設路由表。Of course, if you don't like this convention, you can change the default route table.

一旦找到相符的路由,Web API 會選取控制器和動作:Once a matching route is found, Web API selects the controller and the action:

  • 若要尋找控制器,將 Web API"控制器"的值 {controller} 變數。To find the controller, Web API adds "Controller" to the value of the {controller} variable.
  • 若要尋找此動作,Web API 會查看 HTTP 動詞命令,並接著會尋找名稱開頭為該 HTTP 指令動詞名稱的動作。To find the action, Web API looks at the HTTP verb, and then looks for an action whose name begins with that HTTP verb name. 例如,透過 GET 要求,Web API 會尋找動作前面加上"取得",例如"GetContact"或是"GetAllContacts"。For example, with a GET request, Web API looks for an action prefixed with "Get", such as "GetContact" or "GetAllContacts". 這個慣例僅適用於 GET、 POST、 PUT、 DELETE、 HEAD、 選項和 PATCH 動詞命令。This convention applies only to GET, POST, PUT, DELETE, HEAD, OPTIONS, and PATCH verbs. 您可以使用屬性控制站上,以啟用其他 HTTP 動詞命令。You can enable other HTTP verbs by using attributes on your controller. 我們稍後所見的範例。We'll see an example of that later.
  • 其他的預留位置變數在路由範本中,這類 {id}, 會對應至動作參數。Other placeholder variables in the route template, such as {id}, are mapped to action parameters.

讓我們看看一個範例。Let's look at an example. 假設您定義下列控制器:Suppose that you define the following controller:

public class ProductsController : ApiController
{
    public IEnumerable<Product> GetAllProducts() { }
    public Product GetProductById(int id) { }
    public HttpResponseMessage DeleteProduct(int id){ }
}

以下是一些可能的 HTTP 要求,以及每個叫用的動作:Here are some possible HTTP requests, along with the action that gets invoked for each:

HTTP VerbHTTP Verb URI 的路徑URI Path 動作Action 參數Parameter
GETGET api/productsapi/products GetAllProductsGetAllProducts (none)(none)
GETGET api/products/4api/products/4 GetProductByIdGetProductById 44
DELETEDELETE api/products/4api/products/4 DeleteProductDeleteProduct 44
POSTPOST api/productsapi/products (沒有相符項目)(no match)

請注意, {id} 區段的 URI,如果有的話,會對應至識別碼動作參數。Notice that the {id} segment of the URI, if present, is mapped to the id parameter of the action. 在此範例中,控制器會定義兩個 GET 方法,一個具有識別碼參數和一個不含任何參數。In this example, the controller defines two GET methods, one with an id parameter and one with no parameters.

另外,請注意,POST 要求將會失敗,因為控制器不會定義"文章..."方法。Also, note that the POST request will fail, because the controller does not define a "Post..." method.

路由的變化Routing Variations

上一節所述的基本 ASP.NET Web API 路由機制。The previous section described the basic routing mechanism for ASP.NET Web API. 本章節描述一些變化。This section describes some variations.

HTTP 指令動詞HTTP verbs

而不是使用 HTTP 動詞命令的命名慣例,您可以裝飾具有下列屬性的其中一個動作方法,明確指定動作的 HTTP 動詞命令:Instead of using the naming convention for HTTP verbs, you can explicitly specify the HTTP verb for an action by decorating the action method with one of the following attributes:

  • [HttpGet]
  • [HttpPut]
  • [HttpPost]
  • [HttpDelete]
  • [HttpHead]
  • [HttpOptions]
  • [HttpPatch]

在下列範例中,FindProduct方法會對應至 GET 要求:In the following example, the FindProduct method is mapped to GET requests:

public class ProductsController : ApiController
{
    [HttpGet]
    public Product FindProduct(id) {}
}

若要允許多個 HTTP 動詞命令動作,或允許 GET、 PUT、 POST、 DELETE、 HEAD、 選項和修補程式以外的 HTTP 指令動詞,請使用[AcceptVerbs]屬性,根據 HTTP 指令動詞的清單。To allow multiple HTTP verbs for an action, or to allow HTTP verbs other than GET, PUT, POST, DELETE, HEAD, OPTIONS, and PATCH, use the [AcceptVerbs] attribute, which takes a list of HTTP verbs.

public class ProductsController : ApiController
{
    [AcceptVerbs("GET", "HEAD")]
    public Product FindProduct(id) { }

    // WebDAV method
    [AcceptVerbs("MKCOL")]
    public void MakeCollection() { }
}

路由動作名稱Routing by Action Name

這個預設路由範本中,Web API 會使用 HTTP 動詞命令,來選取的動作。With the default routing template, Web API uses the HTTP verb to select the action. 不過,您也可以建立的路由,其中包含 URI 中的動作名稱:However, you can also create a route where the action name is included in the URI:

routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

此路由範本中, {action} 參數名稱控制站上的動作方法。In this route template, the {action} parameter names the action method on the controller. 使用這種路由方法,使用屬性來指定允許的 HTTP 動詞命令。With this style of routing, use attributes to specify the allowed HTTP verbs. 例如,假設您的控制器具有下列方法:For example, suppose your controller has the following method:

public class ProductsController : ApiController
{
    [HttpGet]
    public string Details(int id);
}

在此情況下,"api/產品/詳細資料/1"的 GET 要求會對應至Details方法。In this case, a GET request for "api/products/details/1" would map to the Details method. 這種路由樣式類似於 ASP.NET MVC,並可能是適當的 RPC 樣式 API。This style of routing is similar to ASP.NET MVC, and may be appropriate for an RPC-style API.

您可以使用覆寫動作名稱[ActionName]屬性。You can override the action name by using the [ActionName] attribute. 在下列範例中,有兩個動作對應至"縮圖 api/產品 / /識別碼。其中一個支援 GET,另支援文章:In the following example, there are two actions that map to "api/products/thumbnail/id. One supports GET and the other supports POST:

public class ProductsController : ApiController
{
    [HttpGet]
    [ActionName("Thumbnail")]
    public HttpResponseMessage GetThumbnailImage(int id);

    [HttpPost]
    [ActionName("Thumbnail")]
    public void AddThumbnailImage(int id);
}

非動作Non-Actions

若要防止方法叫用動作,請使用[NonAction]屬性。To prevent a method from getting invoked as an action, use the [NonAction] attribute. 這表示 framework 方法不是動作,即使否則找到相符的路由規則。This signals to the framework that the method is not an action, even if it would otherwise match the routing rules.

// Not an action method.
[NonAction]  
public string GetPrivateData() { ... }

進一步閱讀Further Reading

本主題提供路由的高層級檢視。This topic provided a high-level view of routing. 如需詳細資訊,請參閱 < 路由和動作選取,其中描述完全如何架構符合路由的 URI、 選取控制器,然後選取要叫用動作。For more detail, see Routing and Action Selection, which describes exactly how the framework matches a URI to a route, selects a controller, and then selects the action to invoke.