在ASP.NETWeb 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 / values
/ api / values / 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属性来修饰Action方法,而不是对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}参数命名控制器上的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() { ... }