傻瓜教你看清MVC内部执行流程之ViewData数据传输,轻松学MVC--①目了然篇(待续)
1.首先在执行到Controller里面的action(方法)时,执行到最后会调用一个View()-->此方法是Controller的一个方法
源代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
protected internal ViewResult View() { return View(null /* viewName */, null /* masterName */, null /* model */); }
2.然后继续调用自己的View(参数1,参数2,参数3)带三个参数的view()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
protected internal virtual ViewResult View(string viewName, string masterName, object model) { if (model != null) { ViewData.Model = model; } return new ViewResult { ViewName = viewName, MasterName = masterName, ViewData = ViewData, TempData = TempData }; }
3.在上步View(string viewName, string masterName, object model)执行完毕将数据封装到ViewResult(ActionResult的子类)中以后MVC会自己调用ViewResult的父类ViewResultBase的ExecuteResult(),方法里面会封装好viewContext对象,并调用IView接口的Render()方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } //其中会判断View()是否有action名,没有则会默认将"路由里面"的action赋值给ViewName if (String.IsNullOrEmpty(ViewName)) { ViewName = context.RouteData.GetRequiredString("action"); } ViewEngineResult result = null; if (View == null) { result = FindView(context); View = result.View; } TextWriter writer = context.HttpContext.Response.Output; //封装数据到viewContext上下文中 ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer); View.Render(viewContext, writer);//调用IView接口的Render()方法 if (result != null) { result.ViewEngine.ReleaseView(context, View); } }
未完待续...
4.而IView接口是由BuildManagerCompiledView类实现的,此类乃是一个抽象类,最终是有WebFormView类来继承并重写了RenderView方法,最终完成ViewData赋值给ViewPage类的ViewData字典属性,最后完成输出显示
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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); } protected abstract void RenderView(ViewContext viewContext, TextWriter writer, object instance);
5.WebFormView类来继承并重写了RenderView方法,最终完成ViewData赋值给ViewPage类的ViewData字典属性,最后调用pr方法走完请求管道,页面生命周期最终完成MVC的数据的呈现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//重写父类的抽象方法 protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance) { ViewPage viewPage = instance as ViewPage; if (viewPage != null) { // RenderViewPage(viewContext, viewPage); return; } ViewUserControl viewUserControl = instance as ViewUserControl; if (viewUserControl != null) { RenderViewUserControl(viewContext, viewUserControl); return; } throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, MvcResources.WebFormViewEngine_WrongViewBase, ViewPath)); } private void RenderViewPage(ViewContext context, ViewPage page) { if (!String.IsNullOrEmpty(MasterPath)) { page.MasterLocation = MasterPath; } page.ViewData = context.ViewData; //调用ViewPage的RenderView方法,然后调用pr方法走完请求管道,页面生命周期最终完成MVC的数据的呈现 page.RenderView(context); }