我的显示模板“ 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.cshtml重命名为MyPlan.cshtml并使用

@Html.DisplayForModel()


一切正常。您能帮我理解为什么会这样吗?

谢谢!

编辑:

如果我按照上面描述的那样完全按照显示模板文件名与视图模型名称匹配的方式进行操作,但是我将视图名称(“ MyPlan”)传递给DisplayForModel,它仍然会引发异常!没有参数的情况下调用DisplayForModel是可行的。这对我来说似乎很奇怪。几乎就像一个错误,但我敢肯定这只是我不了解的事情。

最佳答案

DisplayForModel()(和DisplayFor(m => m))方法在内部使用TemplateHelpers类中的internal static方法。代码非常复杂,我将留给您详细研究源代码,但总结发生的情况:

当您不传递templateName值时,帮助程序基本上会说

查找与我的模型名称匹配的视图名称,并根据该视图为我的收藏集中的每个项目生成html

但是当您确实传递templateName值时,帮助程序基本上会说

找到与templateName匹配的视图并将我的集合传递给它,并基于该视图生成html

这会导致您的异常,因为它会将IEnumerable<MyPlan>模型传递给需要MyPlan模型的视图。

这与使用[TemplateHint]属性时的工作原理相同-即将模型传递给视图,因此模型为IEnumerable<T>,视图也必须为@model IEnumerable<T>

因此,这是设计使然(不是错误),并且确实为您提供了很大的灵活性(例如,允许您为同一模型使用多个模板),尽管该行为可能未得到应有的详细记录。

10-05 19:57