我有一个页面:
<%@ Page Inherits="System.Web.Mvc.View<DTOSearchResults>" %>
关于它,以下内容:
<% Html.RenderPartial("TaskList", Model.Tasks); %>
这是DTO对象:
public class DTOSearchResults
{
public string SearchTerm { get; set; }
public IEnumerable<Task> Tasks { get; set; }
这是部分:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Task>>" %>
当Model.Tasks不为null时,一切正常。但是当它为null时我得到:
传递到字典中的模型项是类型的 'DTOSearchResults'但这个字典需要一个类型的模型项 'System.Collections.Generic.IEnumerable`1 [任务]'。
我认为它一定不知道使用哪个重载,所以我这样做(见下文)是明确的,但我仍然遇到同样的问题!
<% Html.RenderPartial("TaskList", (object)Model.Tasks, null); %>
我知道我可以通过检查null或者甚至不传递null来解决这个问题,但这不是重点。为什么会这样?
答案 0 :(得分:337)
安德鲁我认为你得到的问题是RenderPartial方法的结果,当你传递的模型为null时,使用调用(视图)的模型到局部视图。你可以通过这样做来解决这个奇怪的行为:
<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary()); %>
这有帮助吗?
答案 1 :(得分:44)
@ myandmycode的答案很好,但稍微短一些就是
<% Html.RenderPartial("TaskList", new ViewDataDictionary(Model.Tasks)); %>
这是有效的,因为ViewDataDictionary
是持有模型的东西,它可以接受模型作为构造函数参数。这基本上传递了一个“整个”视图数据字典,当然它只包含可能为空的模型。
答案 2 :(得分:24)
看来,当您传入的Model的属性为null时,MVC会故意恢复为“父”模型。显然,MVC引擎将空模型值解释为使用前一个模型值的意图。
这里稍微详细一点:ASP.NET MVC, strongly typed views, partial view parameters glitch
答案 3 :(得分:19)
如果您不想在局部视图中丢失以前的ViewData,可以尝试:
<% Html.RenderPartial("TaskList", Model.Tasks, new ViewDataDictionary(ViewData){Model = null});%>
答案 4 :(得分:11)
解决方案是创建一个像这样的HtmlHelper:
public static MvcHtmlString Partial<T>(this HtmlHelper htmlHelper, string partialViewName, T model)
{
ViewDataDictionary viewData = new ViewDataDictionary(htmlHelper.ViewData)
{
Model = model
};
return PartialExtensions.Partial(htmlHelper, partialViewName, model, viewData);
}
在Partial<T>(...)
之前匹配的Partial(...)
如此方便,编译时没有歧义错误。
我个人觉得很难理解这种行为 - 似乎很难想象这是设计选择吗?
答案 5 :(得分:11)
虽然已经回答了这个问题,但我遇到了这个问题并决定我想为我的项目解决这个问题而不是使用new ViewDataDictionary()
解决这个问题。
我创建了一组扩展方法:
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<object>
模型的方法,丢弃的模型也可以用Razor lambda调用,允许你用一些html包装部分结果。
如果你愿意,可以随意使用它们。
答案 6 :(得分:0)
我的解决方法是:
<% Html.RenderPartial("TaskList", Model.Tasks ?? new List()); %>