傻瓜教你看清MVC内部执行流程之ViewData数据传输,轻松学MVC--①目了然篇(待续)

1.首先在执行到Controller里面的action(方法),执行到最后会调用一个View()-->此方法是Controller的一个方法

源代码:

View Code
protected internal ViewResult View()

{

            return View(null /* viewName */, null /* masterName */, null /* model */);

}

 

 2.然后继续调用自己的View(参数1,参数2,参数3)带三个参数的view()   

    

View Code
 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的父类ViewResultBaseExecuteResult(),方法里面会封装好viewContext对象,并调用IView接口的Render()方法

   

View Code
      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字典属性,最后完成输出显示

  

View Code
      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的数据的呈现     

重写父类的抽象方法
//重写父类的抽象方法     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);
     }

 

posted @ 2012-09-05 18:50  ajie1166  阅读(2009)  评论(0编辑  收藏  举报