路由如何在 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() { ... }