asp.net-web-api 路由在ASP.NET WebAPI中的工作方式

示例

在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() { ... }