如果我的视图继承自:
System.Web.Mvc.ViewPage<Foo>
Foo有一个带有类型字符串
的属性栏
并且视图想要呈现继承自:
System.Web.Mvc.ViewUserControl<string>
像这样:
Html.RenderPartial("_Bar", Model.Bar);%>
那为什么它会抛出这个:
传递到字典中的模型项的类型为'Foo' 但是这个字典需要一个'System.String'类型的模型项。
什么时候没有初始化吧?
更具体:为什么它传递Foo,它应该传递null?
答案 0 :(得分:35)
正如@Dennis所指出的,如果模型值为null,它将使用视图中的现有模型。这样做的原因是支持使用仅包含部分视图名称的签名调用部分视图并使其重用现有模型的能力。在内部,所有RenderPartial助手都遵循单个RenderPartialInternal方法。您获得该方法以重用现有模型的方法是为模型传递空值(仅采用视图名称的签名)。将空值传递给包含视图名称和模型对象的签名时,基本上复制了仅包含视图名称的方法的行为。
这可以解决您的问题:
<% Html.RenderPartial( "_Bar", Model.Bar ?? string.Empty ) %>
答案 1 :(得分:9)
查看ASP.NET MVC源代码(HtmlHelper.cs - &gt; RenderPartialInternal方法 - &gt;第258行):
...
if (model == null) {
if (viewData == null) {
newViewData = new ViewDataDictionary(ViewData);
}
...
这正是你的情况。 ASP.NET MVC使用ViewContext中的ViewData
<强>更新:强>
请改为尝试:
<% Html.RenderPartial("_Bar", Model.Bar ?? "Default" ); %>
答案 2 :(得分:4)
如果将null作为模型传递给RenderPartial,那么它将查看原始模型,这就是错误说foo的原因。
您需要确保将条初始化为空字符串而不是null。
编辑: @Arnis,看一下源代码。它不是谎言。 您将null传递给RenderPartial的重载。您没有传递 Foo 。在内部,当您将null Bar 传递给RenderPartial时,系统会使用页面的ViewContext中的Model( Foo )。
答案 3 :(得分:4)
虽然已经回答了这个问题,但我遇到了这个问题并决定我想为我的项目解决这个问题,而不是使用新的ViewDataDictionary()&#39;来解决这个问题。
我创建了一组扩展方法:
https://github.com/q42jaap/PartialMagic.Mvc/blob/master/PartialMagic.Mvc/PartialExtensions.cs
如果模型为null,我还添加了一些不调用partial的方法,这将节省很多if语句。
我为Razor创建了它们,但其中一些也应该使用aspx样式视图(使用HelperResult的视图可能不兼容)。
扩展方法如下所示:
@* calls the partial with Model = null *@
@Html.PartialOrNull("PartialName", null)
@* does not call the partial if the model is null *@
@Html.PartialOrDiscard("PartialName", null)
还有IEnumerable模型的方法,丢弃的模型也可以用Razor lambda调用,允许你用一些html包装部分结果。
如果你愿意,可以随意使用它们。