我有一个对象,其中包含我的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为null。我在强类型部分视图中遇到的错误是“此视图需要FooBar2类型的模型,但得到的类型为FooBarHolder。”
为什么会发生这种情况而不只是传入空?
答案 0 :(得分:8)
这就是RenderPartial方法的工作原理(我知道应该记录下来,博客上等等......我也觉得这有点奇怪)。如果您未指定模型或传递null
,它将使用父页面的模型。为避免这种情况,您可以使用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模型的情况。
答案 1 :(得分:2)
为避免在子模型为null时传递父模型,请使用此技巧:
@Html.Partial("Child", null, new ViewDataDictionary<ChildType>(childInstance/*this can be null*/))
答案 2 :(得分:1)
我对这个奇怪的“功能”(或可能是错误?)的解决方法是:
<% Html.RenderPartial(
"Foo2",
new ViewDataDictionary(ViewData) { Model = Model.FooBar2 }
); %>