本节将接着《白话学习MVC(九)View的呈现一》来继续对ViewResult的详细执行过程进行分析!
9、ViewResult
ViewResult将视图页的内容响应给客户端!
由于ViewResult的View呈现过程比较复杂,在此先大致描述一下整个流程:
- 获取视图引擎,默认有两个:ASPX引擎、Razor引擎。
- 根据视图页名称,通过视图引擎去检查是否存在对应的视图页,如果存在,则创建视图对象。如果不存在,则将所有视图引擎寻找过的路径作为异常返回。
- 创建视图对象之后,处理视图页中的内容(先处理_ViewStart.cshtml,之后再处理相应的试图页)。例如:TempData、Html.XXX等。
- 视图页内容处理完毕之后,就将视图内容作为响应返回给客户端。
注:由于对于ASP.NET MVC来说,xxx.cshtml文件称为视图,而对于视图引擎来说,实现IView接口的类称为视图,为了避免混淆,有如下定义:
【视图引擎】泛指那些实现了IViewEngine接口的类,如:WebFormViewEngine、RazorViewEngine。
【视图】泛指那些实现了IView接口的类,如:WebViewPage、RazorView。
【视图页】例如:xxx.cshtml文件或xxx.aspx文件。
【视图页的名称】指视图页的文件名。
对于ViewResult,它有一个父类ViewResultBase,其中定义着一些必要的属性和ExecuteResult方法!
public abstract class ViewResultBase : ActionResult { private DynamicViewDataDictionary _dynamicViewData; private TempDataDictionary _tempData; private ViewDataDictionary _viewData; private ViewEngineCollection _viewEngineCollection; private string _viewName; public object Model { get { return ViewData.Model; } } public TempDataDictionary TempData { get { if (_tempData == null) { _tempData = new TempDataDictionary(); } return _tempData; } set { _tempData = value; } } public IView View { get; set; } public dynamic ViewBag { get { if (_dynamicViewData == null) { _dynamicViewData = new DynamicViewDataDictionary(() => ViewData); } return _dynamicViewData; } } public ViewDataDictionary ViewData { get { if (_viewData == null) { _viewData = new ViewDataDictionary(); } return _viewData; } set { _viewData = value; } } //获取或设置视图引擎,ASP.NET有两个视图引擎,分别是:WebFormViewEngine、RazorViewEngine。 public ViewEngineCollection ViewEngineCollection { get { return _viewEngineCollection ?? ViewEngines.Engines; } set { _viewEngineCollection = value; } } public string ViewName { get { return _viewName ?? String.Empty; } set { _viewName = value; } } public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } //如果没有指定视图页名称将当前Action作为视图页的名称 if (String.IsNullOrEmpty(ViewName)) { ViewName = context.RouteData.GetRequiredString("action"); } ViewEngineResult result = null; if (View == null) { //通过视图引擎去创建视图对象(实现了IView接口的类) result = FindView(context); View = result.View; } TextWriter writer = context.HttpContext.Response.Output; ViewContext viewContext = new ViewContext(context, View, ViewData, TempData, writer); //使用指定的编写器对象来呈现指定的视图上下文 View.Render(viewContext, writer); if (result != null) { result.ViewEngine.ReleaseView(context, View); } }