路由如何在 asp.net webapi 中工作
在 ASP.NET Web API 中,控制器是一個處理 HTTP 請求的類。控制器的公共方法稱為操作方法或簡單的操作。
當 Web API 框架收到請求時,它會將請求路由到操作。要確定要呼叫的操作,框架使用路由表。Web API 的 Visual Studio 專案模板建立了一個預設路由:
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "**api/{controller}/{id}**",
defaults: new { id = RouteParameter.Optional }
);
此路由在 WebApiConfig.cs 檔案中定義,該檔案位於 App_Start 目錄中:
路由表中的每個條目都包含一個路由模板。Web API 的預設路由模板是api / {controller} / {id}。在此模板中,api是文字路徑段,{ controller }和{ id }是佔位符變數。
當 Web API 框架收到 HTTP 請求時,它會嘗試將 URI 與路由表中的某個路由模板進行匹配。如果沒有路由匹配,則客戶端收到 404 錯誤。
例如,以下 URI 與預設路由匹配:
- / API /值
- / API /值/ 1
但是,以下 URI 不匹配,因為它缺少api段:
- /值/ 1
找到匹配的路由後,Web API 將選擇控制器和操作:
- 要查詢控制器,Web API 會將
Controller
新增到{controller}變數的值中。 - 要查詢操作,Web API 會檢視 HTTP 方法,然後查詢名稱以該 HTTP 方法名稱開頭的操作。例如,對於 GET 請求,Web API 會查詢以“Get …”開頭的操作,例如
GetEmployee
或GetAllEmployees
。此約定僅適用於 GET,POST,PUT 和 DELETE 方法。
你可以使用控制器上的屬性啟用其他 HTTP 方法。我們稍後會看到一個例子。
- 路徑模板中的其他佔位符變數(例如{id})將對映到操作引數。
HTTP 方法你可以通過使用 HttpGet,HttpPut,HttpPost 或 HttpDelete 屬性修飾操作方法,而不是使用 HTTP 方法的命名約定,而是顯式指定操作的 HTTP 方法。
在以下示例中,EmployeeGetEmployee 方法對映到 GET 請求:
public class EmployeesController : ApiController
{
[HttpGet]
public EmployeeGetEmployee(id) {}
}
要允許多個 HTTP 方法執行操作,或允許除 GET,PUT,POST 和 DELETE 之外的 HTTP 方法,請使用 AcceptVerbs 屬性,該屬性採用 HTTP 方法列表。
public class EmployeesController: ApiController
{
[AcceptVerbs("GET", "HEAD")]
public Employee GetEmployee (id) { }
}
按操作名稱路由
使用預設路由模板,Web API 使用 HTTP 方法選擇操作。但是,你也可以建立一個路徑,其中操作名稱包含在 URI 中:
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
在此路由模板中,{action}引數在控制器上命名操作方法。使用此樣式的路由,使用屬性指定允許的 HTTP 方法。例如,假設你的控制器具有以下方法:
public class EmployeesController: ApiController
{
[HttpGet]
public List<Employee> GetAllEmployees();
}
在這種情況下,對api / Employees / GetAllEmployees 的 GET 請求將對映到 GetAllEmployees 方法。
你可以使用 ActionName 屬性覆蓋操作名稱。在以下示例中,有兩個操作對映到“ api / Employees / ShowAllEmployees / id 。一個支援 GET,另一個支援 POST:
public class EmployeesController : ApiController
{
[HttpGet]
[ActionName("ShowAllEmployees")]
public List<Employee> GetAll(int id);
[HttpPost]
[ActionName("ShowAllEmployees")]
public void GetAll (int id);
}
非操作
我們可以通過使用 NonAction 屬性來阻止將方法作為操作進行呼叫。這向框架發出訊號,表明該方法不是動作,即使它與路由規則匹配。
[NonAction]
public string GetValues() { ... }