ASP.NET MVC由以下两个核心组成部分构成:
一个名为
UrlRoutingModule
的自定义HttpModule
,用来解析Controller
与Action
名称;
一个名为MvcHandler
的自定义HttpHandler
,用来实现对Controller
的激活和Action
的执行;
!!阅读本文前请先弄明白asp.net执行的流程及httpmodule
与httphandler
的作用。
下面是进行路由转换时相关类的简化结构图:
整个ASP.NET MVC
系统的路由信息全部存放在RouteTable
这个类的静态变量Routes
(为一个RouteDictionary
类型)中,网站开始运行时,在Application_Start
中对路由进行注册:
RouteTable.Routes.Add("default",
new Route{Url="{controller}/{action}"});
当一个URL请求到来时,被UrlRoutingModule
拦截,拦截后执行流程如下:
封装当前http上下文,变为
HttpContextWrapper
对象。
根据当前的http上下文,从Routes
中得到与当前请求URL相符合的RouteData
对象。该对象存储有RouteHandler
信息。
把RouteData
与http
上下文请求封装成一个RequestContext
对象。
根据RequestContext
对象,从RouteData
的RouteHandler
中获取IHttpHandler
。
执行IHttpHandler
,进行请求的真正处理。
执行时序图如下图所示:
UrlRoutingModule
的代码如下:
HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current);
RouteData routeData = RouteTable.Routes.GetRouteData(httpContext);
RequestContext requestContext = new RequestContext{ data = routeData, context= httpContext};
IHttpHandler handler = routeData.RouteHandler.GetHttpHandler(requestContext);
httpContext.RemapHandler(handler);
经过上面最后一步,执行HttpHandle
后,程序正式进入Controller
激活里面,相关类关系如下图所示:
同URL路由一样,MVC
初始化时,也需要注册控制器的一些信息,这里是要让框架知道默认的控制器工厂是什么,所以在Application_Start
中:
ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory());
程序通过上面的URL
路由转换后,进入HttpHandle
中,经过以下步骤实现对Controller
的激活:
- 从
Requestcontext
封装的RouteData
中得到Controller
名字。 - 通过
ControllerBuilder
得到当前默认的Controller
工厂。 - 根据
Controller
的名字,创建控制器对象(在ControllerFactory
初始化的时候,会扫描整个程序集中所有实现IController
接口的控制器类型,所以当调用CreateController
时,实际上是直接获取)。 - 最后执行控制器。执行的实质其实就是执行
ActionInvoker.InvokeAction
,即根据请求上下文执行相应的Action
。
在自定义的MvcHandler
中,代码如下:
string controllerName =this.Requestcontext.RouteData.Controller;
IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory(); //通过controllerName得到Control(如HomeController)
IController controller = controllerFactory.CreateController(this.RequestContext,controllerName);
controller.Execute(this.RequestContext);
一个典型的IActionInvoker
接口实现ControllerActionInvoker
的InvokeAction
方法如下:
public void InvokeAction(ControllerContext controllerContext,
string actionName)
{
//找到Action方法
MethodInfo method = controllerContext.Controller.GetType().GetMethods()
.First(m=>string.Compare(actionName,m.Name,true)==0);
//获取Action参数,并进行Model绑定
List<object> parameters = new List<object>();
foreach(ParameterInfo parameter in method.GetParameters())
{
parameters.Add(this.ModelBinder.BindModel(controllerContext,
parameter.Name, parameter.ParameterType));
}
//执行Action,并得到ActionResult
ActionResult actionResult = method.Invoke(controllerContext.Controller,
parameters.ToArray()) as ActionResult;
//最终ActionResult用HttpResponse将数据传回客户进行显示
actionResult.ExecuteResult(controllerContext);
}
最终形成一个Http Response
传回到客户端!!
以上即为我整理的ASP.NET MVC
的两个核心流程,希望新手看的明白,老手多多指点其中的问题,谢谢!!有时间会继续放出MVC
其它核心技术。如Model
绑定、数据验证等,同时认真向Artech学习!!!!