我有一页:
<%@ 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>>" %>
当模型。Tasks不是空的,一切正常。然而,当它为空时,我得到:
传递到字典中的模型项是类型的
'DTOSearchResults'但是这个字典需要一个类型的模型项
“System.Collections.Generic.IEnumerable”1[任务]”。
我认为它一定不知道使用哪个重载,所以我这样做(见下文)是明确的,但我仍然得到相同的问题!
<% Html.RenderPartial("TaskList", (object)Model.Tasks, null); %>
我知道我可以通过检查null来解决这个问题,甚至不传递null,但这不是重点。为什么会这样?
一个解决方案是创建一个像这样的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(…)之前,因此在编译时方便且没有歧义错误。
我个人觉得很难理解这种行为——似乎很难想象这是一种设计选择?
虽然这个问题已经得到了回答,但我遇到了这个问题,并决定在我的项目中解决这个问题,而不是使用新的ViewDataDictionary()来解决它。
我创建了一组扩展方法:
https://github.com/q42jaap/PartialMagic.Mvc/blob/master/PartialMagic.Mvc/PartialExtensions.cs
我还添加了一些方法,如果模型为空就不调用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包装部分结果。
如果你喜欢,可以随意使用。