Daniel Santos
Daniel Santos

Reputation: 15808

ASP.NET MVC. How use DisplayNameFor in order to create a table heading and body?

How get a property display name using DisplayNameFor()to build a table header. for instance:

   @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>

what should I write in the question marks?

Upvotes: 7

Views: 4527

Answers (3)

user3559349
user3559349

Reputation:

DisplayNameFor() has an overload that accepts IEnumerable<T> so it simply needs to be

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

Note that this only works where the the model is Enumerable<T> (in you case @model IEnumerable<Item>).

But will not work if the model was an object containing a proeprty which was IEnumerable<T>.

For example, the following will not work

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

and it would need to be

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

which will work even if the collection contains no items.

Side note: Under some circumstances, you may initially get a razor error, but you can ignore it. Once you run the app, that error will disappear.

Upvotes: 10

Alisson Reinaldo Silva
Alisson Reinaldo Silva

Reputation: 10695

You could do like this:

   @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>

It may look like you are actually getting the first item of the IEnumerable, but you are not.

Since the parameter you are passing to DisplayFor() is just an Expression Tree, it won't execute IEnumerable's First() method at all, internally DisplayFor() will only check for the passed type (the parameter's type) to use reflection and build a display for it.

Upvotes: 3

Max Toro
Max Toro

Reputation: 28608

If you change the model to an IList<Item> or Item[] you can do this:

   @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>

Upvotes: 1

Related Questions