虽然上面的回答可能是正确的,但我想添加一些更“基本”的东西:
-MVC .NET 中有(很多)隐式路由行为
- 你也可以让一切都变得明确
那么,这对 .NET MVC 有什么作用呢?
默认
- 默认的“路由”是 protocol://server:port/ ,例如http://localhost:607888/
如果你没有任何带有显式路由的控制器,并且没有定义任何启动默认值,那将不起作用。这会:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Special}/{action=Index}");
});
控制器路由
如果你添加一个类Special Controller : Controller和一个 Index() 方法,你的http://localhost:.../就会在那里。注意: 名称控制器 => 修复后控制器被省略,隐式命名约定
如果您更愿意在控制器上显式定义路由,请使用以下命令:
[Route("Special")]//explicit route
public class SpecialController : Controller
{ ....
=> http://localhost:<port>/Special will end up on this controller
为了将 http 请求映射到控制器方法,您还可以将显式 [Route(...)] 信息添加到您的方法中:
// GET: explicit route page
[HttpGet("MySpecialIndex")]
public ActionResult Index(){...}
=> http://localhost:<port>/Special/MySpecialIndex will end up on SpecialController.Index()
查看路线
现在假设您的 Views 文件夹是这样的:
Views\
Special1\
Index1.cshtml
Special\
Index.cshtml
控制器如何“找到”通往视图的路径?这里的例子是
[Route("Special")]//explicit route
public class Special1Controller : Controller
{
// GET: Default route page
[HttpGet]
public ActionResult Index()
{
//
// Implicit path, implicit view name: Special1<Controller> -> View = Views/Special/Index.cshtml
//
//return View();
//
// Implicit path, explicit view name, implicit extention
// Special <Controller> -> View = Views/Special/Index.cshtml
//
//return View("Index");
//
// Everything explcit
//
return View("Views/Special1/Index1.cshtml");
}
所以,我们有:
返回视图();=> 一切都是隐含的,将方法名称作为视图,将控制器路径作为视图路径等。 http://<>:<>/Special => Method = Index(), View = /Views/Special/Index.cshtml
返回视图(“索引”);//显式视图名称,隐式路径和扩展 => Method = Special1Controller.Index(), View = /Views/Special/Index.cshtml
return View("Views/Special1/Index1.cshtml"); // 方法隐式,视图显式 => http://<>:<>/Special, Method = Special1Controller.Index(), View = /Views/Special1/Index1.cshtml
如果您将显式映射结合到方法和视图: => http://<>:<>/Special/MySpecialIndex, Method = Special1Controller.Index(), View = /Views/Special1/Index1.cshtml
最后,你为什么要让一切都隐含?优点是易于出错的管理较少,并且您在文件夹的命名和设置中强制进行一些干净的管理。缺点是很多魔法正在发生,每个人都需要理解。
那你为什么要把一切都说清楚呢?优点:这对“每个人”来说都更具可读性。无需了解所有隐含规则。更灵活地更改路线和地图。控制器和路由路径之间发生冲突的机会也少了一点。
最后:当然你可以混合显式和隐式路由。
我的偏好是一切明确的。为什么?我喜欢显式映射和关注点分离。类名和方法名可以有一个命名约定,而不会干扰您的请求命名约定。例如,假设我的类/方法是 camelCase,我的查询是小写的,那么这会很好地工作:http://..:../whatever/something和 ControllerX.someThing(请记住,Windows 有点不区分大小写,Linux 知道意思是!现代 .netcore Docker 组件可能最终会出现在 Linux 平台上!)我也不喜欢带有 X000 行代码的“大单体”类。通过给它们显式相同的 http 查询路由,拆分您的控制器而不是您的查询可以完美地工作。底线:知道它是如何运作的,并明智地选择一种策略!