PartialViewResult不鳥_ViewStart.cshtml

概述

  在ASP.NET MVC中,對於Action中獲得的ActionResult若是是一個ViewResult對象,那麼在進行View呈現時,則會先執行_ViewStart.cshtml,而後再去執行被請求的視圖頁,可是若是在控制器的Action中獲得的ActionResult是一個PartialViewResult對象,那麼在進行View呈現時,則不會執行_ViewStart.cshtml。html

舉例驗證

例如:控制器代碼以下:web

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View("Index");
        }

        public ActionResult PartView()
        {
            return PartialView("Index");
        }
    }

⑴ 若是視圖中設置以下,即:將 Layout = "~/Views/Shared/_Layout.cshtml";定義在Index.cshtml中。
ide

則ViewResult和PartialViewResult的輸出結果相同:
ui

⑵ 若是視圖設置以下,即:將 Layout = "~/Views/Shared/_Layout.cshtml";定義在_ViewStart.cshtml中。

this

則ViewResult和PartialViewResult的輸出結果不一樣:
spa

   以上的實例,咱們可見判定,對於PartialViewResult對象進行View呈現時,不會執行 「_ViewStart.cshtml」(由於第二種狀況下沒有執行母板頁中的代碼),爲了更加具備說服力,咱們再來看看ASP.NET MVC源代碼,並對比ViewResult和PartialViewResult來檢查咱們的猜測是否正確!!3d

源碼驗證

   因爲對於ASP.NET MVC來講,進行View呈現的入口是執行ActionResult的ExecuteResult方法,而ViewResult和PartialViewResult都是繼承自ViewResultBase類,在ViewResultBase中定義了ExecuteResult 方法!orm

public abstract class ViewResultBase : ActionResult
{
	//省略其餘代碼...
	
	public override void ExecuteResult(ControllerContext context)
	{
		if (context == null)
		{
			throw new ArgumentNullException("context");
		}
		if (string.IsNullOrEmpty(this.ViewName))
		{
			this.ViewName = context.RouteData.GetRequiredString("action");
		}
		ViewEngineResult viewEngineResult = null;
		if (this.View == null)
		{
			//執行FindView方法(在派生類中實現),經過視圖引擎來建立視圖對象!
			viewEngineResult = this.FindView(context);
			this.View = viewEngineResult.View;
		}
		TextWriter output = context.HttpContext.Response.Output;
		ViewContext viewContext = new ViewContext(context, this.View, this.ViewData, this.TempData, output);
		this.View.Render(viewContext, output);
		if (viewEngineResult != null)
		{
			viewEngineResult.ViewEngine.ReleaseView(context, this.View);
		}
	}
	//該方法在派生類ViewResult和PartialViewResult中實現
	protected abstract ViewEngineResult FindView(ControllerContext context);
}

   上圖能夠看出,在ViewResult和PartialViewResult的FindView方法中,分別經過base.ViewEngineCollection的FindView和FindPartialView來建立ViewEngineResult對象(用於封裝當前請求的視圖對象和視圖引擎對象),咱們知道base.ViewEngineCollection其實就是一個視圖引擎集合(默認狀況下有:RazorViewEngine、WebFormViewEngine),而視圖引擎集合的FindView和FindPartialView方法,本質上就是遍歷執行每一個視圖引擎的FindView和FindPartialView方法。htm

  因爲咱們使用的是Razor引擎,全部就以RazorViewEngine爲例來介紹:對象

 

this.CreatePartialView(...)和this.CreateView(...)方法都實如今派生類中!

 

  上圖中,咱們能夠看出在建立RazorView對象時,ViewResult和PartialViewResult的區別在於參數:runViewStartPages,正式因爲它,決定了在以後執行進行視圖頁處理時,也就是執行RazorView對象的Render(viewContext, output)方法時,是否執行「_ViewStar.cshtml」。

public abstract class BuildManagerCompiledView : IView
{
	//省略其餘代碼...
	
	public void Render(ViewContext viewContext, TextWriter writer)
	{
		if (viewContext == null)
		{
			throw new ArgumentNullException("viewContext");
		}
		object obj = null;
		Type compiledType = this.BuildManager.GetCompiledType(this.ViewPath);
		if (compiledType != null)
		{
			obj = this._viewPageActivator.Create(this._controllerContext, compiledType);
		}
		if (obj == null)
		{
			throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.CshtmlView_ViewCouldNotBeCreated, new object[]
			{
				this.ViewPath
			}));
		}
		this.RenderView(viewContext, writer, obj);
	}
	//實如今派生類中
	protected abstract void RenderView(ViewContext viewContext, TextWriter writer, object instance);
}

public class RazorView : BuildManagerCompiledView
{
	//省略其餘代碼...
	
	protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance)
	{
		if (writer == null)
		{
			throw new ArgumentNullException("writer");
		}
		WebViewPage webViewPage = instance as WebViewPage;
		if (webViewPage == null)
		{
			throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.CshtmlView_WrongViewBase, new object[]
			{
				base.ViewPath
			}));
		}
		webViewPage.OverridenLayoutPath = this.LayoutPath;
		webViewPage.VirtualPath = base.ViewPath;
		webViewPage.ViewContext = viewContext;
		webViewPage.ViewData = viewContext.ViewData;
		webViewPage.InitHelpers();
		if (this.VirtualPathFactory != null)
		{
			webViewPage.VirtualPathFactory = this.VirtualPathFactory;
		}
		if (this.DisplayModeProvider != null)
		{
			webViewPage.DisplayModeProvider = this.DisplayModeProvider;
		}
		WebPageRenderingBase startPage = null;
		//在這裏這裏這裏這裏....
		if (this.RunViewStartPages)
		{       //執行「_ViewStart.cshtml」中內容!
			startPage = this.StartPageLookup(webViewPage, RazorViewEngine.ViewStartFileName, this.ViewStartFileExtensions);
		}
		WebPageBase arg_D3_0 = webViewPage;
		HttpContextBase httpContext = viewContext.HttpContext;
		WebPageRenderingBase page = null;
		object model = null;
		arg_D3_0.ExecutePageHierarchy(new WebPageContext(httpContext, page, model), writer, startPage);
	}
}
相關文章
相關標籤/搜索