【问题标题】:Passing null child object from parent object to a partial view将空子对象从父对象传递到局部视图
【发布时间】:2015-09-30 09:34:13
【问题描述】:

我有一个对象,其中包含我的 ASP.NET MVC Web 应用程序的模型。被传递到视图中的模型在该特定视图上具有“小工具”的子模型。这些子模型中的每一个都被传递到局部视图(小工具)。

问题是当我在视图模型中有一个空模型时。请参见下面的示例。

查看模型:

public class FooBarHolder()
{
     public FooBar1 FooBar1 { get; set; }
     public FooBar2 FooBar2 { get; set; }
}

我们将 FooBarHolder 传递到视图中,并在视图内部进行调用,例如

<% Html.RenderPartial("Foo", Model.FooBar1); %>
<% Html.RenderPartial("Foo2", Model.FooBar2); %>

现在假设 Model.FooBar2 为空。我从强类型部分视图中遇到的错误是“此视图需要 FooBar2 类型的模型,但得到了 FooBarHolder 类型的模型。”

为什么会发生这种情况,而不是仅仅传入一个 null?

【问题讨论】:

    标签: c# asp.net-mvc


    【解决方案1】:

    这就是RenderPartial 方法的工作原理(我知道应该记录在案、写博客等等……,我也觉得这有点奇怪)。如果您不指定模型或传递null,它将使用父页面的模型。为避免这种情况,您可以使用空合并运算符:

    <% Html.RenderPartial("Foo", Model.FooBar1 ?? new Foo()); %>
    

    如果您真的很好奇它是如何实现的,那么可以从 ASP.NET MVC 2 源代码的相关部分摘录:

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

    注意 null 模型的情况是如何处理的。

    【讨论】:

    • 感谢您的清晰解释,如果不是您,可能会被困几个小时!在您的情况下,您创建了一个新的 Foo() ,如果您真的想在那里传递 null 怎么办?
    • 子对象为空,它正在恢复为我的父模型。感谢您的澄清。愿你的生活充满独角兽之吻,以及 Care Bear 的吃喝玩乐和彩虹。
    【解决方案2】:

    为避免在子模型为空时传递父模型,请使用以下技巧:

    @Html.Partial("Child", null, new ViewDataDictionary<ChildType>(childInstance/*this can be null*/))
    

    Credit where due...

    【讨论】:

      【解决方案3】:

      我对这个奇怪的“功能”(或者可能是错误?)的解决方法是:

      <% Html.RenderPartial(
          "Foo2", 
          new ViewDataDictionary(ViewData) { Model = Model.FooBar2 }
      ); %>
      

      【讨论】:

        猜你喜欢
        • 2012-03-08
        • 1970-01-01
        • 1970-01-01
        • 2017-12-16
        • 2013-05-08
        • 1970-01-01
        • 1970-01-01
        • 2012-02-13
        • 1970-01-01
        相关资源
        最近更新 更多