zoukankan      html  css  js  c++  java
  • 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)。

    以上就是这两个方法的区别,不知道有没有讲清楚,当然里面还有一些东西我不清楚的,如果大家也意识到那些东西,可以提出来大家一起聊聊,互相学习,多谢。

  • 相关阅读:
    左孩子右兄弟的字典树
    UVA 1401 Remember the Word
    HDOJ 4770 Lights Against Dudely
    UvaLA 3938 "Ray, Pass me the dishes!"
    UVA
    Codeforces 215A A.Sereja and Coat Rack
    Codeforces 215B B.Sereja and Suffixes
    HDU 4788 Hard Disk Drive
    HDU 2095 find your present (2)
    图的连通性问题—学习笔记
  • 原文地址:https://www.cnblogs.com/LJP-JumpAndFly/p/3957570.html
Copyright © 2011-2022 走看看