3

我的显示模板“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 有效。这对我来说似乎非常非常奇怪。几乎就像一个错误,但我敢肯定这只是我不明白的事情。

4

2 回答 2

3

(DisplayForModel()DisplayFor(m => m)) 方法在内部使用TemplateHelpers类中的internal static方法。代码非常复杂,我将留给您更详细地探索源代码,但总结一下会发生什么:

当您不传递templateName值时,助手基本上会说

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

但是当你传递一个templateName值时,助手基本上会说

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

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

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

所以这是设计使然(不是错误),它确实为您提供了很大的灵活性(例如,允许您为同一模型使用多个模板),尽管该行为可能没有像应有的那样有据可查。

于 2016-03-10T03:30:45.530 回答
0

您的模板需要一个单一 MyPlan 实例的模型,因为您的视图有一个 MyPlan 对象列表。因为您没有向 DisplayForModel 提供任何对象,所以它只是从视图中传递模型。为了做你想做的事,你必须将 DisplayForModel 包装在一个 for 循环中,并在循环的每次迭代中从 IEnumerable 传递一个 MyPlan 的实例,即

foreach(var myPlan in Model)
{
    @Html.DisplayForModel("PlanAlternate", myPlan)
}

我没有检查语法,但对我来说这看起来是正确的。

于 2013-06-25T15:54:50.490 回答