
- 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包含:
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
} public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
); } protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
}
在Area中也发现一个注册Route的Max_AdminAreaRegistration.cs类,代码片段:
using System.Web.Mvc; namespace mvcPro.Areas.Max_Admin
{
public class Max_AdminAreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Max_Admin";
}
} public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Max_Admin_default",
"Max_Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
}
界面上出现发现有多个HomeContoller,这是就跑出异常了,这也正常,通过反射寻找HomeController找到两个,不能决定执行哪一个,理所当然。
怎么处理:
我们分别在Global.asax.cs的RegisterRoute函数中修改代码为:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new[] { "mvcPro.Controllers" }
); }
修改Max_AdminAreaRegistration.cs函数RegisterArea函数中修改代码为:
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Max_Admin_default",
"Max_Admin/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }, // Parameter defaults
new[] { "mvcPro.Areas.Max_Admin.Controllers" }
);
}
解决方案参考:http://*.com/questions/7842293/multiple-types-were-found-that-match-the-controller-named-home