【问题标题】:ASP.NET MVC. How use DisplayNameFor in order to create a table heading and body?ASP.NET MVC。如何使用 DisplayNameFor 来创建表格标题和正文?
【发布时间】:2016-12-26 01:51:47
【问题描述】:

如何使用DisplayNameFor()获取属性显示名称来构建表头。例如:

   @model IEnumerable<Item>
   <table class="table">
        <thead>
            <tr>
                <td>@Html.DisplayNameFor(? => ?.prop1)</td>
                <td>@Html.DisplayNameFor(? => ?.prop2)</td>
                <td>@Html.DisplayNameFor(? => ?.prop3)</td>
            </tr>
        </thead>
        <tbody>
            @foreach (Item item in Model) {
                <tr>
                    <td>@Html.DisplayFor(i => item.prop1)</td>
                    <td>@Html.DisplayFor(i => item.prop2)</td>
                    <td>@Html.DisplayFor(i => item.prop3)</td>
                </tr>
            }    
        </tbody>
    </table>

问号应该写什么?

【问题讨论】:

  • 使用LabelFor() 是不合适的(它会生成一个旨在与表单控件关联的标签,但您有很多)。使用@Html.DisplayNameFor(m =&gt; m.prop1)
  • 谢谢@StephenMuecke,我已经编辑了问题。
  • 那么你现在有什么问题? (参见我之前评论中的代码)
  • 是的,我知道。试试看 :) (DisplayNameFor() 有一个 overload 代表 IEnumerable&lt;T&gt;
  • @WillRay,该链接中的答案是正确且必要的,因为model 不是IEnumerable&lt;T&gt;(它的模型包含IEnumerable&lt;T&gt; 的属性)-我正在尝试找到一个合适的骗子,但如果没有,我会添加一个答案

标签: c# asp.net asp.net-mvc razor displayfor


【解决方案1】:

DisplayNameFor() 有一个 overload 接受 IEnumerable&lt;T&gt; 所以它只需要是

<td>@Html.DisplayNameFor(m => m.prop1)</td>

请注意,这仅适用于模型为 Enumerable&lt;T&gt;(在您的情况下为 @model IEnumerable&lt;Item&gt;)的情况。

但如果模型是一个包含IEnumerable&lt;T&gt; 属性的对象,则不会工作

例如,以下将不起作用

<td>@Html.DisplayNameFor(m => m.MyCollection.prop1)</td>

它必须是

<td>@Html.DisplayNameFor(m => m.MyCollection.FirstOrDefault().prop1)</td>

即使集合不包含任何项目,它也会起作用。

旁注:在某些情况下,您最初可能会遇到剃刀错误,但您可以忽略它。运行应用程序后,该错误就会消失。

【讨论】:

  • 我实际上比我更喜欢你的回答,我不知道那个超载。如果MyCollection 是一个IEnumerable,那么你需要使用m.MyCollection.First().prop1 之类的东西,不是吗?因为它不是一个数组,所以你不能使用MyCollection[0]。对吗?
  • @Alisson,您的权利(索引器将用于IList&lt;T&gt; 的属性) - 已更新。
【解决方案2】:

你可以这样做:

   @model IEnumerable<Item>
   <table class="table">
        <thead>
            <tr>
                <th>@Html.DisplayNameFor(i => i.First().prop1)</th>
                <th>@Html.DisplayNameFor(i => i.First().prop2)</th>
                <th>@Html.DisplayNameFor(i => i.First().prop3)</th>
            </tr>
        </thead>
        <tbody>
            @foreach (Item item in Model) {
                <tr>
                    <td>@Html.DisplayFor(i => item.prop1)</td>
                    <td>@Html.DisplayFor(i => item.prop2)</td>
                    <td>@Html.DisplayFor(i => item.prop3)</td>
                </tr>
            }    
        </tbody>
    </table>

看起来您实际上获得了 IEnumerable 的第一项,但实际上并没有。

由于您传递给DisplayFor() 的参数只是一个表达式树,它根本不会执行IEnumerable 的First() 方法,内部DisplayFor() 只会检查传递的类型(参数的类型)以使用反射并为它构建一个显示。

【讨论】:

  • 如果列表为空怎么办?
  • @DanielSantos 它仍然有效,因为DisplayFor 不会尝试从表达式树中获取一些对象实例,它只会分析其元数据以便为其构建显示。 i.First().prop1 不会在那里被调用,这就是为什么这样使用没有问题。试试看。
  • 应该是 中的 标签而不是
  • 你是对的,我只是从问题中复制了示例代码,并没有注意这一点。已修复,非常感谢。
【解决方案3】:

如果您将模型更改为IList&lt;Item&gt;Item[],您可以这样做:

   @model IList<Item>
   <table class="table">
        <thead>
            <tr>
                <td>@Html.DisplayNameFor(x => x[0].prop1)</td>
                <td>@Html.DisplayNameFor(x => x[0].prop2)</td>
                <td>@Html.DisplayNameFor(x => x[0].prop3)</td>
            </tr>
        </thead>
        ...
    </table>

【讨论】:

  • 如果项目列表为空,这将失败。最好在创建表格之前添加条件。
  • @AnkitVijay lambda 表达式没有被执行,只是被分析了。
  • 我可能对列表有误,但是,我觉得我们仍然会在不需要时执行所有这些代码行。如果条件可以拯救我们?
  • @MaxToro 这就是为什么我认为没有必要使用IList&lt;Item&gt;Item[]。代码将仅分析表达式以获取元数据并构建显示。即使IEnumerable 为空,它也会起作用。实际上我认为即使使用空模型也应该可以工作,因为代码根本不会从表达式树中获取对象实例。
猜你喜欢
相关资源
最近更新 更多
热门标签