DisplayForModel具有视图名称参数错误
本文关键字:参数 错误 视图 DisplayForModel | 更新日期: 2023-09-27 18:19:54
我的显示模板"PlanAlternate":
@model MyPlan
<div class="span4 compare-column compare-column1">
<div class="compare-row-plan">
<h3>@Model.Plan.Name</h3>
</div>
@foreach (var benefit in Model.Plan.Benefits)
{
<div class="compare-row-benefit-description">
@benefit.Description
</div>
}
<div class="compare-row-submit">
<input class="btn" type="submit" value="Apply Now" />
</div>
</div>
使用显示模板的我的视图:
@model IEnumerable<MyPlan>
<div class="span9 compare-data-wrapper">
@Html.DisplayForModel("PlanAlternate")
</div>
这引发了一个异常:
传递到字典中的模型项的类型为"System.Collections.Generic.List`1[MyPlan]",但此字典需要类型为"MyPlan"的模型项。
但是,如果我将显示模板从PlanAlternate.chtml重命名为MyPlan.chtml并使用
@Html.DisplayForModel()
一切都很好。你能帮我理解为什么会发生这种事吗?
谢谢!
编辑:
如果我完全按照上面描述的那样,显示模板文件名与视图模型名匹配,但我将视图名("MyPlan")传递给DisplayForModel,它仍然会抛出异常!!调用不带参数的DisplayForModel是可行的。这对我来说非常非常奇怪。几乎就像一个bug,但我确信这只是我不明白的事情。
DisplayForModel()
(和DisplayFor(m => m)
)方法在内部使用TemplateHelpers类中的internal static
方法。代码相当复杂,我将让您更详细地探索源代码,但要总结一下发生了什么:
当您没有传递templateName
值时,助手基本上会说
为我找到与我的模型名称匹配的视图名称,并基于该视图为我的收藏中的每个项目生成html
但是,当您传递templateName
值时,助手基本上会说
找到与templateName匹配的视图,并将我的集合传递给它,并基于该视图生成html
这会导致您的异常,因为它将IEnumerable<MyPlan>
的模型传递给期望模型为MyPlan
的视图。
这与使用[TemplateHint]
属性时的工作原理相同,即它将模型传递给视图,因此如果模型是IEnumerable<T>
,则视图也必须是@model IEnumerable<T>
。
因此,它是经过设计的(不是一个bug),它确实给了你很大的灵活性(例如,允许你为同一个模型使用多个模板),尽管行为可能没有得到应有的良好记录。
您的模板需要一个单一MyPlan实例的模型,其中您的视图有一个MyPlan对象列表。因为您没有向DisplayForModel提供任何对象,所以它只是从视图传递模型。要执行您想要的操作,您必须将DisplayForModel封装在for循环中,并在循环的每次迭代中从IEnumerable传递MyPlan的实例,即
foreach(var myPlan in Model)
{
@Html.DisplayForModel("PlanAlternate", myPlan)
}
我还没有检查语法,但我觉得很正确。