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)。

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

  • 相关阅读:
    POJ 2251 Dungeon Master(BFS)
    POJ 1321 棋盘问题 (DFS + 回溯)
    POJ 3009 Curling 2.0(DFS + 模拟)
    Codeforces 702D Road to Post Office(模拟 + 公式推导)
    Codeforces 702A Maximum Increase(dp)
    Codeforces 702C Cellular Network(二分)
    Codeforces 702B Powers of Two
    POJ 3083 Children of the Candy Corn (DFS + BFS + 模拟)
    POJ 2488 A Knight's Journey (回溯法 | DFS)
    POJ1094 Sorting It All Out (拓扑排序)
  • 原文地址:https://www.cnblogs.com/LJP-JumpAndFly/p/3957570.html
Copyright © 2011-2022 走看看