具有嵌套模型类的Razor视图

时间:2013-01-11 20:28:39

标签: c# asp.net-mvc razor

我有一个嵌套类,例如:

public class Jar
{
    public IEnumerable<NailClippings> Nails { set; get; }
    public IEnumerable<People> Donors { set; get; }
}

我的控制器将单个Jar传递给我的视图,字符串键入为

@model Test.ViewModels.Jar

我可以使用类似的内容轻松遍历NailsDonors的内容

@foreach(var item in Model.Nails)

我的问题是使用HTML帮助器为我生成显示名称

@Html.DisplayNameFor(model => model.Nails.Length)

我通过将内部嵌套类的类型更改为List,在查询结束时附加.ToList()并将行更改为

来提出解决方案
@Html.DisplayNameFor(model => model.Nails[0].Length)

强制使用List并使用索引[0]来显示名称对我来说太愚蠢了。是否有另一种引用内部嵌套类属性的方法?

修改:查看

<table>
    <tr>
        <th>@Html.DisplayNameFor(model => model.Nails[0].Length)</th>
        .
        .
    </tr>
    @foreach(var item in Model.Nails){
    <tr>
        <td>@Html.DisplayFor(modelItem => item.Length</td>
        .
        .
    </tr>
    }
</table>

4 个答案:

答案 0 :(得分:8)

您无需在视图中编写任何循环。这让他们变得如此丑陋。

只需为集合类型定义相应的显示模板即可。因此,例如,您将创建~/Views/Shared/DisplayTemplates/NailClippings.cshtml部分视图,该视图将强烈类型化为集合的单个元素:

@model NailClippings
<tr>
    <td>
        @Html.DisplayFor(x => x.Length)
    </td>
    .
    .
</tr>

现在在主视图中,它就像:

一样简单
@model Jar
<table>
    <thead>
        <tr>
            <th>Length</th>
            .
            .
        </tr>
    </thead>
    <tbody>
        @Html.DisplayFor(x => x.Nails)
    </tbody>
</table>

显示/编辑器模板按惯例工作。因此,当您在主视图中使用@Html.DisplayFor(x => x.Nails)时,ASP.NET MVC将分析Nails属性的类型,并将看到它是IEnumerable<NailClippings>集合。因此,它将首先在~/Views/CurrentController/DisplayTemplates/NailClippings.cshtml内,然后在~/Views/Shared/DisplayTemplates/NailClippings.cshtml内开始寻找相应的显示模板,最后它将回退到default display template。当选择模板时,ASP.NET MVC将为集合属性的每个元素自动为您执行此模板,这样您就不必担心在视图中编写一些循环,担心索引,... < / p>

这也适用于编辑器模板:@Html.EditorFor(x => x.Nails)将查找~/Views/Shared/EditorTemplates/NailClippings.cshtml。您获得的奖励是生成的输入字段将具有正确的名称,并且当您提交表单时,默认模型绑定器将自动为您的视图模型重新水化HttpPost操作作为请求中的参数。

基本上,如果您尊重框架遵循的惯例,您将使您的生活更轻松。

答案 1 :(得分:4)

而不是

model.Nails[0].Length

您可以使用

model.Nails.First().Length

无需转换为List

答案 2 :(得分:2)

我认为你可以使用item循环变量

@Html.DisplayNameFor(model => item.Length)

更新另一个选项是为Nails显示创建部分视图。它将强烈输入IEnumerable<NailClippings>并且所有属性都可用:

@Html.Partial("_Nails", Model.Nails)

指甲局部视图:

@model IEnumerable<NailClippings>

<table>
    <tr>
        <th>@Html.DisplayNameFor(model => model.Length)</th>
        .
        .
    </tr>
    @foreach(var item in Model){
    <tr>
        <td>@Html.DisplayFor(modelItem => item.Length)</td>
        .
        .
    </tr>
    }
</table>

答案 3 :(得分:0)

我认为这个示例代码对嵌套模型类

很有用
@model ViewModels.MyViewModels.Theme

@Html.LabelFor(Model.Theme.name)
@foreach (var category in Model.Theme)
{
   @Html.LabelFor(category.name)
   @foreach(var product in theme.Products)
   {
      @Html.LabelFor(product.name)
      @foreach(var order in product.Orders)
      {
          @Html.TextBoxFor(order.Quantity)
          @Html.TextAreaFor(order.Note)
          @Html.EditorFor(order.DateRequestedDeliveryFor)
      }
   }
}