尽管其他答案可能是正确的,我想补充一些更基础的内容:
- 在MVC .NET中有很多隐式路由行为。
- 您也可以使所有内容都变得显式。
那么,这对于.NET MVC来说如何工作呢?
默认情况下:
- 默认“路由”是protocol://server:port/ ,例如http://localhost:607888/
- 如果您没有任何具有显式路由的控制器,并且没有定义任何启动默认值,则无法正常工作。
- 下面的代码可以解决这个问题:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Special}/{action=Index}");
});
控制器路由:
如果您添加一个名为SpecialController的类和一个Index()方法,则您的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")]
public class Special1Controller : Controller
{
[HttpGet]
public ActionResult Index()
{
return View("Views/Special1/Index1.cshtml");
}
所以,我们有:
return View();
=> 一切都是隐式的,将方法名称作为视图,将控制器路径作为视图路径等。
http://<>:<>/Special => Method = Index(), View = /Views/Special/Index.cshtml
return View("Index");
//显式视图名称,隐式路径和扩展名
=> 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 and ControllerX.someThing
(请记住,Windows有点不区分大小写,Linux绝对不是!并且现代.netcore Docker组件可能最终在Linux平台上运行!)
我也不喜欢具有X000行代码的“大型单体”类。通过将它们显式地赋予相同的HTTP查询路由,拆分控制器但不拆分查询完美地起作用。
底线:了解它的工作原理,并明智地选择一种策略!
View
和PartialView
的调用标记为红色。 - t3chb0t