ASP.NET MVC笔记
ASP.NET MVC的应用程序生命周期还是跟原来ASP.NET WebForm一样没有区别,只是引入MVC后,加了一个UrlRoutingModule模块,该模块用来捕获应用程序生命周期中的PostResolveRequestCache事件,当事件触发时然后选择合适的IHttpHandler来处理请求
那是如何获取IHttpHandler的呢,我们在Global.asax的Application_Start事件中写routes.MapRoute注册路由时,会给路由对象Route创建一个MvcRouteHandler,该对象调用GetHttpHandler方法返回MvcHandler 对象用来处理接下来的操作。我们看到这个处理程序已经不是原来WebForm时的Page了。
获取完IHttpHandler后应用程序生命周期继续往下执行,经过一些事件后最后终于触发了CallHandlerExecutionStep,也就是之前创建的MvcHandler开始要接手处理了,它将会完成接下来的控制器方法执行,以及视图查找和呈现,核心东西都在这里了,所以要好好来分析下。
MvcHandler是一个IHttpAsyncHandler,它是一个异步的,因此它不是执行ProcessRequest方法了,取而代之的是BeginProcessRequest和EndProcessRequest方法。在BeginProcessRequest内部通过调用RequestContext.RouteData获取controller控制器的名字,接下来ControllerFactory根据前面获取的控制器名称来创建controller实例。
接下来MvcHandler执行EndProcessRequest方法,controller实例调用Execute方法,内部通过另一个方法ExecuteCore执行核心操作。该方法中包含了很多的执行步骤,首先调用PossiblyLoadTempData(),控制器上下文ControllerContext判断当前请求是否IsChildAction来决定是否加载TempData数据,如果是ChildAction则不加载。
然后RouteData 获取当前Action的方法名,ControllerActionInvoker调用InvokeAction方法,在InvokeAction方法中执行我们在Controller中定义的方法,执行方法的前后后我们可以注册过滤器,以让我们在执行action的前后做一些自己想做的事情。所以第一步要做的是获取所有注册过滤器,这些过滤器信息获取后存在一个叫FilterInfo对象中,其中包含了AuthorizationFilters,ActionFilters,ResultFilters ,接下来调用方法GetParameterValues(controllerContext, actionDescriptor)来获取action的参数。
调用InvokeActionMethodWithFilters方法执行action和actionfilters,这顺序一般是OnActionExecuting->ActionMethod->OnActionExecuted。这边主要讲ActionMethod方法因为它才真正代表了我们Controller中那些Action所执行的代码。获取Action参数值,封装ActionMethodDispatcher里面包含我们要执行的action的MethodInfo信息,ActionMethodDispatcher 执行Execute进而进入到action的执行,当执行完action通常返回一个ActionResult 这里我们让其返回一个ViewResult(ActionResult的一个子类),当然还有其他ActionResult ,譬如JsonResult,JavaScriptResult,FileResult,EmptyResult等等,而ViewResult 表示我们要向客户端呈现的是一个视图,通常是我们在Views文件夹下建的那些.aspx文件,当然不一定是.aspx,不同的视图引擎实现不一样。当我们写下return View()即表示返回一个ViewResult ,内部调用的是重载的方法View(string viewName, string masterName, object model)方法,你也可以直接调用该方法,顺便传入视图名等其他信息,调用new ViewResult{iewName = viewName, MasterName = masterName, ViewData = ViewData, TempData = TempData},然后返回该对象。执行完ActionMethod后来个OnActionExecuted操作收尾。
调用InvokeActionResultWithFilters方法执行result和resultfilters,这顺序一般是OnResultExecuting->ResultExecut->OnResultExecuted。这边主要讲ResultExecut因为它涉及到视图的查找与呈现,其中视图的呈现类似原来WebForm下Page的执行过程。
调用ViewResult 的FindView方法查找视图。内部通过ViewEngineCollection 的FindView来实现。ViewEngineCollection 是一个视图引擎的集合,在MVC3中包含了两个视图引擎WebFormViewEngine和RazorViewEngine, 查找的过程会先获取Controller的名称,然后结合ViewName,找到视图所在的路径字符串,创建一个View对象,其中属性
ViewPath即为之前找到的视图路径,接着创建ViewEngineResult 对象,将View对象赋给ViewResult的View属性,执行View.Render呈现视图,根据ViewPathViewPath获取视图实例(Page对象),执行Page对象的ProcessRequest方法,这个我想大家都很熟悉了吧,哈哈。
最后释放视图,退出ResultExecute,这样视图的呈现就结束了。
执行OnResultExecuted。调用PossiblySaveTempData保存TempData数据。到这里Controller就执行完成了,退出ExecuteExecute方法,释放Cotroller对象。然后退出MvcHandler的执行,继续应用程序生命周期接下来的那些事件。