Html.Partial("")與Html.RenderPartial("")區別


文章有點長,但大多是代碼,看看很快的,不要壓力太大。網上有很多關於這兩個方法的區別,都說出了它本質的區別(不看代碼,只看這個結論,就已經足夠了,如果覺得有必要從代碼中得出這個結論,那就繼續往下看),這里從代碼中跟大家說說它們的區別,這兩個擴展方法都是用來加載部分視圖,先說下它們本質上的區別, RenderPartial是直接返回一個視圖,而Partial返回的是視圖的字符串,即一個返回視圖對象,一個返回字符串。內部做了什么呢?接下來詳細介紹。
1.Partial

反編譯工具中對這個擴展類的描述如下:Represents the functionality to render a partial view as an HTML-encoded string.大概意思就是生成一個部分頁作為一個HTML字符串(英語比較好的,再翻譯翻譯,哈哈)。

這個方法是HtmlHelper的擴展方法,這個方法有四個重載,用Reflector工具看下,代碼如下:

public static class PartialExtensions
{
// Methods
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName);
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model);
public static MvcHtmlString Partial(this HtmlHelper htmlHelper,string partialViewName,ViewDataDictionary viewData);
public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDicti                                                            onary viewData);
}

四個方法都差不多,區別就是傳給它們的參數(不同的參數都是咱們傳給視圖的數據viewData和model),這里就說說第一個和第四個方法,其他都一樣。

(1)兩個參數的Partial

反編譯工具中代碼如下:

 public static MvcHtmlString Partial(this HtmlHelper htmlHelper, string partialViewName)
 {
     return htmlHelper.Partial(partialViewName, null, htmlHelper.ViewData);
 }

第一個參數是擴展方法的語法,這里就不說了。這個方法又調用了一個Partial方法,這個方法就是HtmlHelper中的原生方法了,進去看看它干了什么:

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());
    }
}

很明顯,它用了一個StringWriter,看到這個肯定就知道跟字符串有關了,再說下里面調用的那兩個方法的作用(直接在代碼里講解啦):

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 dictionary = null;
    if (model == null)
    {
        if (viewData == null)
        {
            dictionary = new ViewDataDictionary(this.ViewData);//這些步驟,肯定是在裝填咱們的數據了,下同
        }
        else
        {
            dictionary = new ViewDataDictionary(viewData);
        }
    }
    else if (viewData == null)
    {
        dictionary = new ViewDataDictionary(model);
    }
    else
    {
        ViewDataDictionary dictionary2 = new ViewDataDictionary(viewData) {//我現在還不明白這個的作用,了解的同志,求教
            Model = model
        };
        dictionary = dictionary2;
    }
    ViewContext viewContext = new ViewContext(this.ViewContext, this.ViewContext.View, dictionary, this.ViewContext                                                          .TempData, writer);
    FindPartialView(viewContext, partialViewName, viewEngineCollection).Render(viewContext, writer);
//這個方法就是用來生成視圖的,具體代碼往下看。Render方法就是講FindPartialView方法返回的視圖寫入writer流,詳情繼續看FindPartialView的代碼。
}
再來看下這個代碼,MvcHtmlString.Create(writer.ToString()),看了這個大家就明白了:
//它先調用這個方法
public
static MvcHtmlString Create(string value) { return new MvcHtmlString(value); } //然后實例化一個MvcHtmlString,大家看到了,其實它就是將剛才寫入writer中的內容轉為字符串,這里就是說Partial返回的是字符串的原因 public MvcHtmlString(string value) : base(value ?? string.Empty) { this._value = value ?? string.Empty; }

最本質的東西大家都看到了,最后再說下FindPartialView這個方法(直接注釋代碼嘍):

internal static IView FindPartialView(ViewContext viewContext, string partialViewName, ViewEngineCollection viewEngineCollection)
{
    ViewEngineResult result = viewEngineCollection.FindPartialView(viewContext, partialViewName);//從視圖引擎集合中搜索名partialViewName視圖
    if (result.View != null)//如果找到該視圖,直接將視圖返回
    {
        return result.View;
    }
    StringBuilder builder = new StringBuilder();//這些代碼就不說了,不知所雲,知道的朋友,求教
    foreach (string str in result.SearchedLocations)
    {
        builder.AppendLine();
        builder.Append(str);
    }
    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, MvcResources.Common_PartialViewNotFound, new object[] { partialViewName, builder }));
}

執行了FindPartialView之后,會返回一個View,返回View之后執行Render方法,Render方法中應該是將這個返回的視圖寫入writer中(反編譯工具沒得看,原理應該是這樣的)。

(2)四個參數的Partial

直接看代碼,大家就清楚了:

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());
    }
}

代碼就是這樣,是不是感覺似曾相識,其實就跟上面說到的代碼一樣,唯一的區別就是有沒有傳入數據。詳情請看之前附上RenderPartialInternal的代碼,就是裝填數據然后調用生成視圖FindPartialView方法,具體看上面哈,這里就不多說了。

Partial方法說到這里。

2.RenderPartial

反編譯工具中對這個擴展類的描述如下:Provides support for rendering a partial view.意思大概是提供支持生成部分頁的方法。

這個方法是HtmlHelper的擴展方法,這個方法同樣有四個重載,用Reflector工具看下,代碼如下:

public static class RenderPartialExtensions
{
    // Methods
    public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName);
    public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model);
    public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData);
    public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName, object model, ViewDataDictionary viewData);
}

有沒有感覺跟Partial方法很相似,只是名字不一樣。是的,不一樣的就是它里面調用的方法,這里就說四個擴展方法中的一個(它們調用的是同一個方法,只是有沒有數據的區別),就說下第一個方法代碼如下:

public static void RenderPartial(this HtmlHelper htmlHelper, string partialViewName)
{
   htmlHelper.RenderPartialInternal(partialViewName, htmlHelper.ViewData, null, htmlHelper.ViewContext.Writer, ViewEngines.Engines);
}

本質的區別就是,在執行了RenderPartialInternal這個方法之后,沒有再執行MvcHtmlString.Create(writer.ToString())這個方法,這就是之前說的Partial是返回字符串,而RenderPartial返回的是視圖的原因。RenderPartialInternal的代碼和Partial方法調用的RenderPartialInternal是一樣的。區別直接上圖比較直觀,如下圖1:

                                  圖1

從圖中可以看出,Partial在生成視圖后,將視圖寫入流中,然后再通過MvcHtmlString.Create方法轉為字符串(具體看Partial中的代碼),而RenderPartial在調用了RenderPartialInternal方法之后就沒有其他操作了(RenderPartialInternal中調用了FinderPartialView方法,此方法中返回View)。

以上就是這兩個方法的區別,不知道有沒有講清楚,當然里面還有一些東西我不清楚的,如果大家也意識到那些東西,可以提出來大家一起聊聊,互相學習,多謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM