- MVC最核心的也就是Controller了,控制器(controller)在功能中起到了核心功能.
1,)在MVC类库中,根据URL,通过MVCHandler进入MVC处理系统中,
2,)解析初始化对应的Route信息,
3,)在MVCHandler的Begin_RequestHandler函数中,根据URL获取到对应的Controller,和Action,
4,)在执行Controller.Execute之前还需要进行一个验证处理,
5,)之后执行Exceute,
6,)在Execute处理过程中需要包含有验证相关处理,需要先处理验证等,
7,)执行Execute处理相关业务信息,返回View,
8,)之后进一步验证信息,
9,)。。。
这里仅仅提到了一个大概的执行流程,但真正的源代码中我们发现每一步处理,都会包含有若干准备出,
比如:根据Controller,Action名称,获取到对应的Controller,和Action后,怎么执行?
1,) 这里就获取通过反射获取对应的Controller实例对象,之后从ControllerContext上下文中获取到对应的参数,以便反射时填充对应的Action函数参数;
2,)这里还包含一个缓存的地方,当第一次找到一个Controller实例时,MVC框架会自动把这样的实例信息存储起来,以便下一次根据Controller和Action的名称,可以快速找到对应的实例。
- 下边我们创建一个asp.net mvc3工程,感受下Controller怎么使用。
我创建了一个HomeController,给该Controller创建了一个View(~/views/Home/Index.cshtml);
我再创建一个Area(Max-Admin),于是就又多了一个Area,在Area中包含一个HomeController,这时候我也给该HomeController添加一个View(~/views/Home/Index.cshtml);
调试项目:页面跑出异常(Multiple types were found that match the controller named ‘Home‘. This can happen if the route that services this request (‘{controller}/{action}/{id}‘) does not specify namespaces to search for a controller that matches the request.)
我们从项目中可以看到Global.asax.cs包含:
1 // Note: For instructions on enabling IIS6 or IIS7 classic mode, 2 // visit http://go.microsoft.com/?LinkId=9394801 3 4 public class MvcApplication : System.Web.HttpApplication 5 { 6 public static void RegisterGlobalFilters(GlobalFilterCollection filters) 7 { 8 filters.Add(new HandleErrorAttribute()); 9 } 10 11 public static void RegisterRoutes(RouteCollection routes) 12 { 13 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 14 15 routes.MapRoute( 16 "Default", // Route name 17 "{controller}/{action}/{id}", // URL with parameters 18 new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 19 ); 20 21 } 22 23 protected void Application_Start() 24 { 25 AreaRegistration.RegisterAllAreas(); 26 27 RegisterGlobalFilters(GlobalFilters.Filters); 28 RegisterRoutes(RouteTable.Routes); 29 } 30 }
在Area中也发现一个注册Route的Max_AdminAreaRegistration.cs类,代码片段:
1 using System.Web.Mvc; 2 3 namespace mvcPro.Areas.Max_Admin 4 { 5 public class Max_AdminAreaRegistration : AreaRegistration 6 { 7 public override string AreaName 8 { 9 get 10 { 11 return "Max_Admin"; 12 } 13 } 14 15 public override void RegisterArea(AreaRegistrationContext context) 16 { 17 context.MapRoute( 18 "Max_Admin_default", 19 "Max_Admin/{controller}/{action}/{id}", 20 new { action = "Index", id = UrlParameter.Optional } 21 ); 22 } 23 } 24 }
界面上出现发现有多个HomeContoller,这是就跑出异常了,这也正常,通过反射寻找HomeController找到两个,不能决定执行哪一个,理所当然。
怎么处理:
我们分别在Global.asax.cs的RegisterRoute函数中修改代码为:
1 public static void RegisterRoutes(RouteCollection routes) 2 { 3 routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 4 5 routes.MapRoute( 6 "Default", // Route name 7 "{controller}/{action}/{id}", // URL with parameters 8 new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults 9 new[] { "mvcPro.Controllers" } 10 ); 11 12 }
修改Max_AdminAreaRegistration.cs函数RegisterArea函数中修改代码为:
1 public override void RegisterArea(AreaRegistrationContext context) 2 { 3 context.MapRoute( 4 "Max_Admin_default", 5 "Max_Admin/{controller}/{action}/{id}", 6 new { action = "Index", id = UrlParameter.Optional }, // Parameter defaults 7 new[] { "mvcPro.Areas.Max_Admin.Controllers" } 8 ); 9 }
解决方案参考:http://stackoverflow.com/questions/7842293/multiple-types-were-found-that-match-the-controller-named-home