ASP.NET Core MVC中的路由是使用路由中间件来匹配传入请求的URL并映射到操作的。
ASP.NET Core MVC中支持两种路由:传统路由和属性路由。
传统路由是什么呢?传统路由是通过约定的形势来进行URL映射的,下面的路由模板约定了URL模板为“控制器/行为/可选参数”,例如:http:120.0.0.1/Home/Index/1会访问到Home控制下的Index方法。(在Program.cs中定义,详细生命周期请参考第六章:中间件)
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
//等价于上面的代码(简便写法)
//app.MapDefaultControllerRoute();
上面的代码示例定义了一个传统的MVC路由,默认会访问Home控制下的Index Action,id?表示该参数为可选参数。
使用这些URL都会命中如下代码中的Action:
public class HomeController : Controller
{
public IActionResult Index() { ... }
}
以Products/Details/5为例,实际会访问以下Action,并携带参数id=5。
模板实际路由值为:{controller=Products}/{action=Details}/{id=5}
public class ProductsController : Controller
{
public IActionResult Details(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
在ASP.NET Core MVC中支持通过在Program.cs中使用MapControllerRoute配置多个传统路由。这样可以定义多个约定或者用于添加专用于特定操作的传统路由,示例代码如下:
app.MapControllerRoute(name: "blog",
pattern: "blog/{*article}",
defaults: new { controller = "Blog", action = "Article" });
app.MapControllerRoute(name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
上面的代码示例定义了两个传统的MVC路由,blog以及defult路由。
使用这些URL会命中如下代码中的blog路由:
defult路由请参考"传统路由"章节。
在上面示例代码中,Blog开头的路由只会命中blog路由,因为blog路由比default路由先定义,优先级比default高。
在ASP.NET Core MVC中支持通过在Program.cs中使用MapControllers来启用属性路由,示例如下:
Program.cs
app.MapControllers();
HomeController.cs
public class HomeController : Controller
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
[Route("Home/Index/{id?}")]
public IActionResult Index(int? id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
[Route("Home/About")]
[Route("Home/About/{id?}")]
public IActionResult About(int? id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
上面的代码示例使用了属性路由,具体URL匹配如下:
命中Home控制器中Index方法的URL:
命中Home控制器中About方法的URL:
HTTP谓词模板
ASP.NET Core MVC中的HTTP谓词模板是路由模板的一种,用于约定好路由的情况下通过HTTP请求方式来命中不同Action,示例如下:
[Route("api/[controller]")]
[ApiController]
public class Test2Controller : ControllerBase
{
//GET
//URL——/api/test2
[HttpGet]
public IActionResult ListProducts()
{
return ControllerContext.MyDisplayRouteInfo();
}
//GET
//URL——/api/test2/xyz
[HttpGet("{id}")]
public IActionResult GetProduct(string id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
//GET
//URL——/api/test2/int/3
[HttpGet("int/{id:int}")]
public IActionResult GetIntProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
在上面示例代码中,给出了最常用的HTTPGet以及HTTPPost的谓词模板的用法,命中URL规则请看注释。