具有嵌套模型类的Razor视图

Jef*_*eff 5 c# asp.net-mvc razor

我有一个嵌套类,如:

public class Jar
{
    public IEnumerable<NailClippings> Nails { set; get; }
    public IEnumerable<People> Donors { set; get; }
}
Run Code Online (Sandbox Code Playgroud)

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

@model Test.ViewModels.Jar
Run Code Online (Sandbox Code Playgroud)

我可以通过内容循环NailsDonors容易像这样的东西

@foreach(var item in Model.Nails)
Run Code Online (Sandbox Code Playgroud)

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

@Html.DisplayNameFor(model => model.Nails.Length)
Run Code Online (Sandbox Code Playgroud)

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

@Html.DisplayNameFor(model => model.Nails[0].Length)
Run Code Online (Sandbox Code Playgroud)

被迫使用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>
Run Code Online (Sandbox Code Playgroud)

Dar*_*rov 8

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

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

@model NailClippings
<tr>
    <td>
        @Html.DisplayFor(x => x.Length)
    </td>
    .
    .
</tr>
Run Code Online (Sandbox Code Playgroud)

现在在主视图中,它很简单:

@model Jar
<table>
    <thead>
        <tr>
            <th>Length</th>
            .
            .
        </tr>
    </thead>
    <tbody>
        @Html.DisplayFor(x => x.Nails)
    </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

显示/编辑器模板按惯例工作.因此,当您使用主视图时@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将为集合属性的每个元素自动为您执行此模板,这样您就不必担心在视图中编写一些循环,担心索引,......

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

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


D S*_*ley 5

代替

model.Nails[0].Length
Run Code Online (Sandbox Code Playgroud)

你可以用

model.Nails.First().Length
Run Code Online (Sandbox Code Playgroud)

无需转换为List.

  • @lazyberezovsky 如果列表中没有项目,则此方法有效。我认为使用 [0] 会破坏它......刚刚测试过它。如果列表为空,则它适用于这两种方法。这个解决方案比我用过的要漂亮得多 (3认同)