MVC 学习系列-Controller

  • 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怎么使用。

MVC 学习系列-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://*.com/questions/7842293/multiple-types-were-found-that-match-the-controller-named-home