这里详细讲解一下C# WebApi路由机制。
什么是C#WebApi路由机制
在C# WebApi中,路由机制(Route mechanism)是指当客户端发送一个HTTP请求到服务端时,系统如何根据请求的URL和HTTP方法来匹配对应的API方法。这个过程就是通过路由机制来实现的。路由机制可以将请求URL和HTTP方法映射到相应的API方法。
路由的两种类型
在C# WebApi中,路由分为两种类型,分别是传统路由(traditional routes)和特性路由(attribute routing)。
传统路由
传统路由将URL分解成受控制器和动作组成的一组段。这些控制器和操作可以由您自己的代码(即您的路由)映射到名称,而该代码是在WebApi应用程序启动时执行的。传统路由的示例:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
路由计算包括以下步骤:
- 检索实现 IHttpControllerSelector 的默认策略对象 (HttpControllerSelector)。
- 选择适合于请求的控制器类型。
- 实例化控制器并调用操作。
- 构建响应并将其发送给客户端。
传统路由的优点是可与 ASP.NET Web Forms 和 MVC 共享,并且不依赖于 ASP.NET Web API。但是,传统路由需要硬编码控制器和操作名称,因此不太灵活。
特性路由
WebApi 2 引入了特性路由,它提供了一种使用属性而不是在路由表中定义路由的方式。这使得 API 代码变得更加直观,因为它将路由信息与 API 方法直接挂接到了一起。
特性路由的示例:
[RoutePrefix("api/employees")]
public class EmployeesController : ApiController
{
[HttpGet]
[Route("getall")]
public IHttpActionResult GetAllEmployees()
{
return Ok();
}
[HttpPost]
[Route("create")]
public IHttpActionResult CreateEmployee(Employee employee)
{
return Ok();
}
}
在上述示例中,RoutePrefix
指示了控制器的路由前缀,这意味着有关控制器的所有Route
属性都将在此前缀之后匹配。Route
属性指示了API方法的具体路由,这些路由会与控制器的路由前缀连接,从而形成完整的路由。
C#WebApi路由的优势
-
灵活性:Web API Routing 允许 Web API 应用程序轻松更改 URI 格式,而无需更改应用程序中的其他代码,因为 Web API 很好地隐藏了 URI 格式。
-
可扩展性:Web API Routing 允许您添加自定义路由规则以控制请求到 API 操作的映射。这种可扩展性使您能够编写可重用,复杂和多样化的 Web API 应用程序。
-
自定义URI格式:Web API Routing 允许 API 操作映射到任何 URI 格式,这使得您可以为 API 开发自己的 URI 格式。
示例1:传统路由
例如,我们可以定义以下 API:
public class ProductsController : ApiController {
public IEnumerable<Product> GetAllProducts() { ... }
public Product GetProductById(int id) { ... }
public IEnumerable<Product> GetProductsByCategory(string category) { ... }
public HttpResponseMessage UpdateProduct(Product product) { ... }
public void DeleteProductById(int id) { ... }
}
我们可以使用以下路由配置来映射请求:
// routes for the products api
config.Routes.MapHttpRoute(
name: "ProductsApi",
routeTemplate: "api/products/{id}",
defaults: new { controller = "products", id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ProductsByCategoryApi",
routeTemplate: "api/products/category/{category}",
defaults: new { controller = "products", action = "getproductsbycategory" }
);
config.Routes.MapHttpRoute(
name: "UpdateProductApi",
routeTemplate: "api/products/{id}",
defaults: new { controller = "products", action = "updateproduct" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Put) }
);
config.Routes.MapHttpRoute(
name: "DeleteProductApi",
routeTemplate: "api/products/{id}",
defaults: new { controller = "products", action = "deleteproductbyid" },
constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Delete) }
);
- 请求
api/products
将映射到GetAllProducts
操作。 - 请求
api/products/{id}
将映射到GetProductById
操作,并且 id 参数将在 URL 中作为路由段。 - 请求
api/products/category/{category}
将映射到GetProductsByCategory
操作,并且 category 参数将在 URL 中作为路由段。 - 请求
api/products/{id}
且带有 PUT 请求方法将映射到UpdateProduct
操作。 - 请求
api/products/{id}
且带有 DELETE 请求方法将映射到DeleteProductById
操作。
示例2:特性路由
我们重新定义相同的 API,使用特性路由法:
[RoutePrefix("api/products")]
public class ProductsController : ApiController {
[HttpGet]
[Route("")]
public IEnumerable<Product> GetAllProducts() { ... }
[HttpGet]
[Route("{id:int}")]
public Product GetProductById(int id) { ... }
[HttpGet]
[Route("category/{category}")]
public IEnumerable<Product> GetProductsByCategory(string category) { ... }
[HttpPut]
[Route("{id:int}")]
public HttpResponseMessage UpdateProduct(Product product) { ... }
[HttpDelete]
[Route("{id:int}")]
public void DeleteProductById(int id) { ... }
}
[RoutePrefix("api/products")]
属性指示了控制器的路由前缀,所有方法的路由都将在此前缀之后匹配。[Route("")]
属性指示映射到GetAllProducts
操作的路由。[Route("{id:int}")]
属性指示映射到GetProductById
操作的路由。其中,{id:int}
表示该路由段应为整数类型。[Route("category/{category}")]
属性指示映射到GetProductsByCategory
操作的路由。[Route("{id:int}")]
和[HttpPut]
属性指示映射到UpdateProduct
操作的路由和请求方法。[Route("{id:int}")]
和[HttpDelete]
属性指示映射到DeleteProductById
操作的路由和请求方法。
这是特性路由的一个例子。通过使用属性路由,可以更清晰地表达每个 Controller 和 Action,使代码更加直观易懂。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# WebApi 路由机制剖析 - Python技术站