路由如何在 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 目录中: StackOverflow 文档

路由表中的每个条目都包含一个路由模板。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 …”开头的操作,例如 GetEmployeeGetAllEmployees。此约定仅适用于 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() { ... }