默认路由设置
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
此路由在 WebApiConfig.cs 文件中定义,该文件放置在 App_Start 目录中
找到匹配路由后,Web API 会选择控制器和操作:
若要查找控制器,Web API 会将“控制器”添加到 {controller} 变量的值。
若要查找操作,Web API 将查看 HTTP 谓词,然后查找名称以该 HTTP 谓词名称开头的操作。 例如,对于 GET 请求,Web API 查找前缀为“Get”的操作,例如“GetContact”或“GetAllContacts”。 此约定仅适用于 GET、POST、PUT、DELETE、HEAD、OPTIONS 和 PATCH 谓词。 可以使用控制器上的属性启用其他 HTTP 谓词。 稍后我们将看到一个示例。
路由模板中的其他占位符变量(如 {id}) 映射到操作参数。
可以使用下列属性之一修饰操作方法,而不是对 HTTP 谓词使用命名约定来显式指定操作的 HTTP 谓词:
[HttpGet]
[HttpPut]
[HttpPost]
[HttpDelete]
[HttpHead]
[HttpOptions]
[HttpPatch]
在以下示例中,该方法 FindProduct 映射到 GET 请求:
public class ProductsController : ApiController
{
[HttpGet]
public Product FindProduct(id) {}
}
若要允许操作的多个 HTTP 谓词,或者允许除 GET、PUT、POST、DELETE、HEAD、OPTIONS 和 PATCH 以外的 HTTP 谓词,请使用采用 [AcceptVerbs] HTTP 谓词列表的属性。
public class ProductsController : ApiController
{
[AcceptVerbs("GET", "HEAD")]
public Product FindProduct(id) { }
// WebDAV method
[AcceptVerbs("MKCOL")]
public void MakeCollection() { }
}
使用默认路由模板,Web API 使用 HTTP 谓词选择操作。 但是,还可以创建一个路由,其中操作名称包含在 URI 中:
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
可以使用属性替代操作名称 [ActionName] 。 在以下示例中,有两个操作映射到“api/products/thumbnail/id”。一个支持 GET,另一个支持 POST:
public class ProductsController : ApiController
{
[HttpGet]
[ActionName("Thumbnail")]
public HttpResponseMessage GetThumbnailImage(int id);
[HttpPost]
[ActionName("Thumbnail")]
public void AddThumbnailImage(int id);
}
[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }
可以使用 [RoutePrefix] 属性为整个控制器设置通用前缀:
[RoutePrefix("api/books")]
public class BooksController : ApiController
{
// GET api/books
[Route("")]
public IEnumerable<Book> Get() { ... }
// GET api/books/5
[Route("{id:int}")]
public Book Get(int id) { ... }
// POST api/books
[Route("")]
public HttpResponseMessage Post(Book book) { ... }
}
使用方法属性上的平铺 (~) 替代路由前缀:
[RoutePrefix("api/books")]
public class BooksController : ApiController
{
// GET /api/authors/1/books
[Route("~/api/authors/{authorId:int}/books")]
public IEnumerable<Book> GetByAuthor(int authorId) { ... }
// ...
}
[Route("users/{id:int}")]
public User GetUserById(int id) { ... }
[Route("users/{name}")]
public User GetUserByName(string name) { ... }