在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
接着上篇文章asp.net mvc源码分析-Action篇 Action的执行 ,现在Action已经执行并且返回结果,在ControllerActionInvoker.InvokeAction方法中 ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters);这句已经执行完毕,现在看看InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);这句是怎么搞得,InvokeActionResultWithFilters方法的代码结构InvokeActionMethodWithFilters一致,从这里我们知道真正的结果处理调用时 InvokeActionResult(controllerContext, actionResult);是这句。该方法的其他部分是调用filter的。InvokeActionResult这个方法很简单就一句 actionResult.ExecuteResult(controllerContext); 我们发现RedirectToRouteResult,RedirectResult,JsonResult,JavaScriptResult,HttpStatusCodeResult,FileResult,ContentResult这几个东西都没有涉及到我们的view,直接继承于ActionResult,他们的特点是直接输出内容,我们以ContentResult为例,它的主要代码如下: public override void ExecuteResult(ControllerContext context) { 同样JavaScriptResult的ExecuteResult也是类似 public override void ExecuteResult(ControllerContext context) { 现在 我们把重心放到涉及到view的ViewResultBase,而ViewResult集成于ViewResultBase且重写了FindView方法。 ViewResultBase有几个属性 public TempDataDictionary TempData 其中 TempData、ViewBag、ViewData的作用和Controll而中对应的属性一致,而Model=ViewData.Model这个也没什么说的了,ViewName简单不说了,通过ViewName可以构建一个View,总之这几个属性很好理解。这里还有一个比较特殊的属性ViewEngineCollection public ViewEngineCollection ViewEngineCollection { public static class ViewEngines { mvc默认给我们提供了WebFormViewEngine和RazorViewEngine,他们分别对应着WebFormView和RazorView这个两个IView的实现,他们都继承于BuildManagerCompiledView。从这个Engines 的定义我们知道我们可以采用自己的ViewEngine,只需要我们在Application_Start方法中添加一句ViewEngines.Engines.Add(xxx);就可以实现自己的ViewEngine。 我们还是先看看Action的返回view()都做了什么。 protected internal ViewResult View() { 从 这里我们可以知道ViewResult的ViewData 就是Controller的ViewData ,TempData 也是Controller的TempData ,ViewResult要么指定View要么指定ViewName。和MasterName。 ViewResult的MasterName如下: public string MasterName { 默认 为空,而在Action返回函数调用最多的还是指定ViewName的这种情况要多一些。 现在 来看看你ViewResultBase中的ExecuteResult方法, public override void ExecuteResult(ControllerContext context) { 从这段代码我们知道,如果 ViewName为空我们把它设为Action的name,如果view为空,我们就调用FindView方法查找View,FindView方法主要是一句 ViewEngineResult result = ViewEngineCollection.FindView(context, ViewName, MasterName); 这里 具体是怎么查找view的我们就先不管了。 WebFormView和RazorView都继承于BuildManagerCompiledView。 TextWriter writer = context.HttpContext.Response.Output;这句就说明说的了, ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer);这句就是实例化一个ViewContext ,没什么特别的只是注意一下ViewContext 继承于ControllerContext。 View.Render(viewContext, writer);这句其实调用的是BuildManagerCompiledView的Render方法: public void Render(ViewContext viewContext, TextWriter writer) { if (viewContext == null) { throw new ArgumentNullException("viewContext"); } object instance = null; Type type = BuildManager.GetCompiledType(ViewPath); if (type != null) { instance = _viewPageActivator.Create(_controllerContext, type); } if (instance == null) { throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, MvcResources.CshtmlView_ViewCouldNotBeCreated, ViewPath ) ); } RenderView(viewContext, writer, instance); } Type type = BuildManager.GetCompiledType(ViewPath);这句很好理解根据当前的view的路径找到相应的Type。实际上就是调用是这句 BuildManager.GetCompiledType(virtualPath),System.Web.dll中BuildManager的具体实现很复杂我们就不管了。这里我们需要注意的是,mvc中的view默认是在第一次运行时动态编译的,并且不同路径下的view是编译到不同的dll中,编译出来的一个WebViewPage<TModel>子类。 instance = _viewPageActivator.Create(_controllerContext, type);这句就是创建一个view类型实例。从BuildManagerCompiledView的构造函数我们知道viewPageActivator 默认是一个DefaultViewPageActivator, _viewPageActivator = viewPageActivator ?? new BuildManagerViewEngine.DefaultViewPageActivator(dependencyResolver); DefaultViewPageActivator的Create方法实现如下: return _resolverThunk().GetService(type) ?? Activator.CreateInstance(type);这种代码在讲Controller是就讲到了,这里不再重复了。 最后在调用 RenderView(viewContext, writer, instance);,这个方法在各自的子类实现了的。 RenderView方法的实现也是很复杂了,先放到后面再说。 现在让我们又回到ExecuteResult方法中来,还有最后一句 if (result != null) { public virtual void ReleaseView(ControllerContext controllerContext, IView view) { 就是调用view的Dispose方法。而BuildManagerCompiledView没有实现IDisposable接口,所以实际上是没有调用所谓的Dispose方法。
|
请发表评论