相信很多人都被 Html.Partial 與 Html.RenderPartial 這兩個給搞糊塗(另一組則是 Html.Action 與 Html.RenderAction,還有 ViewResult 以及 PartialViewResult),這邊就簡單說明一下 Html.Partial 與 Html.RenderPartial 的區別。
PartialExtensions 類別
http://msdn.microsoft.com/zh-tw/library/system.web.mvc.html.partialextensions(v=vs.108).aspx
代表可以將部分檢視轉譯為 HTML 編碼字串的功能。
使用 Html.Partial 的回傳是 MvcHtmlString 的結果,基本常用的使用方式如下:
PartialViewName 如果是與主頁面(例如 Index.cshtml)是同一個目錄,則可以直接填入 PartialViewName,而如果是使用其他目錄(例如 ~/Views/Shared/)的 Partial View 檔案,則可以使用檔案路徑。
PartialExtensions.cs 原始碼:
public static class PartialExtensions
{
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName)
{
return Partial(htmlHelper, partialViewName, null /* model */, htmlHelper.ViewData);
}
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData)
{
return Partial(htmlHelper, partialViewName, null /* model */, viewData);
}
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model)
{
return Partial(htmlHelper, partialViewName, model, htmlHelper.ViewData);
}
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary viewData)
{
using (StringWriter writer = new StringWriter(CultureInfo.CurrentCulture))
{
htmlHelper.RenderPartialInternal(partialViewName, viewData, model, writer, ViewEngines.Engines);
return MvcHtmlString.Create(writer.ToString());
}
}
}
由原始碼可以看到最後是輸出 MvcHtmlString 的結果。
RenderPartialExtensions 類別
http://msdn.microsoft.com/zh-tw/library/system.web.mvc.html.renderpartialextensions(v=vs.108).aspx
提供呈現部分檢視的支援。(這個敘述實在讓人摸不著頭緒)
依據「ASP.net MVC 4 網站開發美學」Page 5-89 關於 RenderPartial 的敘述,RenderPartial 是將結果直接寫入 ViewPage 的 Output Stream。
基本的使用方法如下:
用法跟 Html.Partial 一樣,PartialViewName 如果是與主頁面(例如 Index.cshtml)是同一個目錄,則可以直接填入 PartialViewName,而如果是使用其他目錄(例如 ~/Views/Shared/)的 Partial View 檔案,則可以使用檔案路徑。
RenderPartialExtensions.cs 原始碼:
public static class RenderPartialExtensions
{
// Renders the partial view with the parent's view data and model
public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName)
{
htmlHelper.RenderPartialInternal(partialViewName, htmlHelper.ViewData, null /* model */, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
}
// Renders the partial view with the given view data and, implicitly, the given view data's model
public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData)
{
htmlHelper.RenderPartialInternal(partialViewName, viewData, null /* model */, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
}
// Renders the partial view with an empty view data and the given model
public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model)
{
htmlHelper.RenderPartialInternal(partialViewName, htmlHelper.ViewData, model, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
}
// Renders the partial view with a copy of the given view data plus the given model
public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary viewData)
{
htmlHelper.RenderPartialInternal(partialViewName, viewData, model, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
}
}
在原始碼裡可以看到與 PartialExtensions 不同的是,這邊的 Methods 都是沒有回傳結果,而是最後去執行 HtmlHelper.RenderPartialInternal() 方法,原始碼如下:
internal virtual void RenderPartialInternal(string partialViewName, ViewDataDictionary viewData, object model, TextWriter writer, ViewEngineCollection viewEngineCollection)
{
if (String.IsNullOrEmpty(partialViewName))
{
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "partialViewName");
}
ViewDataDictionary newViewData = null;
if (model == null)
{
if (viewData == null)
{
newViewData = new ViewDataDictionary(ViewData);
}
else
{
newViewData = new ViewDataDictionary(viewData);
}
}
else
{
if (viewData == null)
{
newViewData = new ViewDataDictionary(model);
}
else
{
newViewData = new ViewDataDictionary(viewData) { Model = model };
}
}
ViewContext newViewContext = new ViewContext(ViewContext, ViewContext.View, newViewData, ViewContext.TempData, writer);
IView view = FindPartialView(newViewContext, partialViewName, viewEngineCollection);
view.Render(newViewContext, writer);
}
基本上 Html.Partial 與 Html.RenderPartial 是一樣的,在 Profession ASP.NET MVC 4 裡面有提到,以編輯的方便性來說,建議使用 Html.Partial,因為在 View 使用 Html.RenderPartial 時必須用大括號來包住,如下圖所示:
而 Html.Partial 則不需要用大括號,如下圖:
兩者於其他使用情境上的比較:
在 Profession ASP.NET MVC 4 裡面另外有提到,若是以效能來說, Html.RenderPartial 會比 Html.Partial 來得好些,因為是在內部直接寫入到 ViewPage 的 Output Stream 裡,而 Html.Partial 則因為輸出 MvcHtmlString, ViewPage 於 Render 時會需要另外去處理。
在實務應用上要採用哪一種方法,因為兩者最後所呈現的結果是一樣的,內部也一樣使用了 HtmlHelper.RenderPartialInternal 方法,只是在輸出方式有所不同,所以要用哪一種就看開發者或是開發團隊的習慣、規則而定,如果很看種效能的表現而不在意開發時需要多敲幾下鍵盤,那就使用 Html.RenderPartial 方法。
我是習慣使用 Html.Partial 居多。
以上
Nice!!
回覆刪除解釋得很清楚 讚!
回覆刪除非常感謝你的講解!!!開心~ 感謝~
回覆刪除