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