当来自浏览器的请求到达我们的应用程序时,MVC 中的控制器会处理传入的 http 请求并响应用户操作,请求URL会被映射到控制器的操作方法上。
ASP.NET Core MVC 中 的默认路由
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseMvcWithDefaultRoute();
}
UseMvcWithDefaultRoute()扩展方法将 MVC 与默认路由添加到我们的应用程序的请求处理管道中。
UseMvcWithDefaultRoute()方法中的代码
public static IApplicationBuilder UseMvcWithDefaultRoute(this IApplicationBuilder app)
{
if (app == null)
{
throw new ArgumentNullException(nameof(app));
}
return app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
默认路由模板{controller=Home}/{action = Index}/{id?}
,大多数的URL都会按照这个规则进行映射。问号表示 id 参数可有可无。
{controller=Home}中的"Home"是 Controller的默认值。"Index"是 action 方法的默认值。
如果要定义自己的路径模板,要使用 UseMvc()方法,而不是 UseMvcWithDefaultRoute()方法。
app.UseMvc(routes =>
{
routes.MapRoute("default","{controller=Home}/{action = Index}/{id?}");
});
使用属性路由,可以在Controller或 Controller 的操作方法上应用Route属性。
publicclassHomeController:Controller
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
publicViewResultIndex()
{
returnView();
}
}
3 个 URL 路径中,都会访问 HomeController 的 Index()操作方法:
/
/Home
/Home/Index
1)属性路由和控制器明明、操作方法名称可以不匹配
在属性路由中,控制器名称和操作方法名称,不会影响路由属性名称,他们没有强关联关系。
public class WelcomeController : Controller
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
public ViewResult Welcome()
{
return View();
}
}
2)属性路由支持层次结构
可以在Controller类上定义公共路径。
[Route("Home")]
public class HomeController : Controller
{
private readonly IStudentRepository _studentRepository;
//使用构造函数注入的方式注入IStudentRepository
public HomeController(IStudentRepository studentRepository)
{
_studentRepository = studentRepository;
}
[Route("")]
[Route("Index")]
public IActionResult Index() {
IEnumerable<Student> students = _studentRepository.GetAllStudents();
return View(students);
}
//?使路由模板中的id参数为可选,如果要使它为必选,删除?即可
[Route("Details/{id?}")]
//? 使id方法参数可以为空
public IActionResult Details(int? id)
{
//实例化HomeDetailsViewModel并存储Student详细信息和PageTitle
HomeDetailsViewModel homeDetailsViewModel = new HomeDetailsViewModel()
{//如果"id"为null,则使用1,否则使用路由中传递过来的值
Student = _studentRepository.GetStudent(id??1),
PageTitle = "学生详细信息"
};
return View(homeDetailsViewModel);
}
}
注意:
如果操作方法上的路由模板以/
或 ~/
开头, 则控制器路由模板不会与操作方法路由模板组合在一起。即方法上的路径和类上的路径不会组合在一起。
3)属性路由中自定义路由
标记[controller]和[action]将替换为定义路径的控制器名称和操作名称的值。
[Route("[controller]")]
public class DepartmentsController : Controller
{
[Route("[action]")]
public string List()
{
return " DepartmentsController控制器中的List()方法";
}
[Route("[action]")]
public string Details()
{
return " DepartmentsController控制器中的Details()方法";
}
}
在 URL 路径中的/Departments/List将进入DepartmentsController中执行List()方法。
最好在控制器上只设置一次,而不是在控制器中的每个操作方法中包含[action]标记,如下所示。
[Route("[controller]/[action]")]
public class DepartmentsController : Controller
{
public string List()
{
return " DepartmentsController控制器中的List()方法";
}
public string Details()
{
return " DepartmentsController控制器中的Details()方法";
}
}
通常情况下, 常规路由用于服务 HTML 页的控制器。 而属性路由则用于服务 REST API 的控制器。