将null子对象从父对象传递到局部视图

7 c# asp.net-mvc

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

问题是我在视图模型中有一个空模型.见下面的例子.

查看型号:

public class FooBarHolder()
{
     public FooBar1 FooBar1 { get; set; }
     public FooBar2 FooBar2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

<% Html.RenderPartial("Foo", Model.FooBar1); %>
<% Html.RenderPartial("Foo2", Model.FooBar2); %>
Run Code Online (Sandbox Code Playgroud)

现在说比较Model.FooBar2为null.我从强类型的局部视图中遇到的是一个错误,上面写着"这个视图需要一个类型为FooBar2的模型,但却得到了一个类型为FooBarHolder的模型."

为什么会发生这种情况而不是只传入null?

Dar*_*rov 8

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

<% Html.RenderPartial("Foo", Model.FooBar1 ?? new Foo()); %>
Run Code Online (Sandbox Code Playgroud)

如果您对如何实现它非常好奇,那么可以从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);
}
Run Code Online (Sandbox Code Playgroud)

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