ASP.NET MVC 2 url/路由、视图与控制器有何关系?
有人可以解释一下 MVC 2 中路由如何与控制器关联吗?目前,我在 /Controllers/HomeController.cs 中有一个控制器,并且有一个视图 /Home/Index.aspx。
我的路由注册方法如下所示:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.MapRoute(
"Default",
// Route name
"{controller}/{action}/{id}",
// URL with parameters
new { controller = "Home", action = "Index", id = "" }
// Parameter defaults
);
}
如果我请求 URL:http://localhost/Home/Index,那么该请求将被 HomeController.Index() 正确处理。
然而,在我的一生中,我无法弄清楚 url /Home/Index 是如何指向 HomeController 的。据我所知,视图 aspx 没有引用 HomeController,HomeController 没有引用视图,并且路由表没有明确提及 HomeController。这是如何神奇地发生的?我肯定错过了一些明显的东西。
然后
Could someone explain how routes are associated with controllers in MVC 2? Currently, I have a controller in /Controllers/HomeController.cs and a view /Home/Index.aspx.
My route registration method looks like this:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{resource}.aspx/{*pathInfo}");
routes.MapRoute(
"Default",
// Route name
"{controller}/{action}/{id}",
// URL with parameters
new { controller = "Home", action = "Index", id = "" }
// Parameter defaults
);
}
If I request the URL: http://localhost/Home/Index, then the request is correctly handled by HomeController.Index().
However, for the life of me, I can't figure out how the url /Home/Index gets pointed to HomeController. The view aspx doesn't, as far as I can tell, reference HomeController, HomeController doesn't reference the view, and the route table doesn't explicitly mention HomeController. How is this magically happening? Surely I'm missing something obvious.
then
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是 ASP.NET MVC 中的约定。
当使用 DefaultControllerFactory 时,此约定被隐藏在内部密封类
System.Web.Mvc.ControllerTypeCache
中(Microsoft 编写内部密封类的典型做法)。在里面你会发现一个名为EnsureInitialized
的方法,它看起来像这样:注意分组是如何进行的。因此,基本上 DefaultControllerFactory 将在所有引用的程序集中查找实现 Controller 基类的类型,并从名称中删除“Controller”。
如果你真的想详细剖析 ASP.NET MVC 的管道,我会推荐你这个 优秀文章。
This is the convention in ASP.NET MVC.
When using the DefaultControllerFactory this convention is buried inside the internal sealed class
System.Web.Mvc.ControllerTypeCache
(typical for Microsoft to write internal sealed classes). Inside you will find a method calledEnsureInitialized
which looks like this:Pay attention how the grouping is made. So basically the DefaultControllerFactory will look inside all the referenced assemblies for types implementing the Controller base class and will strip the "Controller" from the name.
If you really want to dissect in details ASP.NET MVC's pipeline I would recommend you this excellent article.
ASP.NET MVC 附带的默认视图引擎遵循以下约定:
您有一个如下所示的文件夹结构:
当请求传入并匹配 RegisterRoutes 方法中定义的路由时(请参见 URL 路由了解更多),然后调用匹配的控制器:
在默认路由中,您还指定了默认控制器(不带“Controller”后缀) - 路由引擎将自动将
Controller
添加到您的控制器名称 - 以及默认操作。在控制器中,您调用简单的方法:
默认视图引擎然后在“Views”文件夹中名为“Home”(与控制器相同)的文件夹中查找名为 Index(与操作相同)的 aspx 文件(习俗)。
如果在那里找不到索引页,它还会在共享文件夹中查找索引页。
来自 ASP.NET MVC 书呆子晚餐示例章节
编辑添加:
我设置的一些示例路由,显式设置控制器是:
这里我明确声明我正在使用相册控制器,以及对其执行 PhotoDetails 操作,并传入各种 id 等到那个动作。
The default views engine that comes with ASP.NET MVC works on the following conventions:
You have a folder structure like this:
When a request comes in, and matches a route defined in the RegisterRoutes method (see things like URL routing for more on that), then the matching controller is called:
In the default route, you are also specifying a default controller (without the "Controller" suffix) - the routing engine will automatically add
Controller
onto the controller name for you - and a default action.In your controller, you call the simple method:
The default view engine then looks for an aspx file called Index (the same as the action) in a folder called "Home" (the same as the controller) in the "Views" folder (convention).
If it doesn't find one in there, it will also look for an index page in the Shared folder.
From the ASP.NET MVC Nerd Dinner sample chapter
Edit to add:
Some example routes I've set up, that explicitly set the controller are:
Here I'm explicitly stating that I'm using the Albums controller, and the PhotoDetails action on that, and passing in the various ids, etc to the that action.
在操作 Index 中有一个语句
return View()
。当返回空白视图时,DefaultViewEngine 会在几个默认文件夹中搜索 Controller 方法的名称(特别是在 FindView 方法内)。其中之一是 Views/Home 目录,因为 Home 是控制器的名称。它在那里找到索引文件,并使用它来显示结果。Inside the action Index there is a statement
return View()
. When a blank View is returned, the DefaultViewEngine searches several default folders for the name of the Controller method(specifically inside the FindView method). One of them is the Views/Home directory because Home is the name of the controller. There it finds the Index file, and uses it to display the result.