Using model property of type IEnumerable<T> for table column headers in ASP.NET MVC

I have paged results class that I am using to display paged data to users. I had problem with getting names of returned result properties to table headers in views. It works automatically if model implements IEnumerable<T> but not if your IEnumerable<T> is property of model. Here is the solution I found from Stack Overflow with little improvement.

Problem

Here is my paged result class:

public class PagedResult<T>

{

    public IList<T> Results { get; set; }

    public int CurrentPage { get; set; }

    public int PageCount { get; set; }

    public int PageSize { get; set; }

    public int RowCount { get; set; }

    public T Type { get { return default(T); } }

 

    public PagedResult()

    {

        Results = new List<T>();

    }

}

You can find my paged result class and examples about how to use it from my posting Returning paged results from repositories using PagedResult.

When I try to use results collection this way:

<tr>
    <th>
        @Html.DisplayFor(model => model.Results.Name)
   
</th>
    <th></th
>
</
tr
>

I get the following error:

CS0411: The type arguments for method ‘System.Web.Mvc.Html.DisplayExtensions.DisplayFor<TModel,TValue>(System.Web.Mvc.HtmlHelper<TModel>, System.Linq.Expressions.Expression<System.Func<TModel,TValue>>, object)’ cannot be inferred from the usage. Try specifying the type arguments explicitly.

Out-of-box DisplayFor<T> is not able to understand what is going on.

Solution

I found solution from Stack Overflow thread @Html.DisplayNameFor for details model. I added fallback from empty display name to original property name and here is the code:

public static MvcHtmlString DisplayColumnNameFor<TModel, TClass, TProperty>(this HtmlHelper<TModel> helper, IEnumerable<TClass> model, Expression<Func<TClass, TProperty>> expression)

{

    var name = ExpressionHelper.GetExpressionText(expression);

    name = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

    var metadata = ModelMetadataProviders.Current.GetMetadataForProperty(

        () => Activator.CreateInstance<TClass>(), typeof(TClass), name);

 

    var returnName = metadata.DisplayName;

    if (string.IsNullOrEmpty(returnName))

        returnName = metadata.PropertyName;

 

    return new MvcHtmlString(returnName);

}

Just add this extension method to some static class and call it like I do:

<tr>
    <th>
        @Html.DisplayColumnNameFor(Model.Results, model => model.Name)
   
</th>
    <th></th
>
</
tr
>

I hope this method finds in future its way to ASP.NET MVC code too.

Liked this post? Empower your friends by sharing it!

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    2 thoughts on “Using model property of type IEnumerable<T> for table column headers in ASP.NET MVC

    • January 30, 2018 at 7:53 am
      Permalink

      I solved that problem by using a special setting for JsonSerializerSettings which is called TypeNameHandling.

    • January 30, 2018 at 7:58 am
      Permalink

      Can you explain more about how you exactly did it?

    Leave a Reply

    Your email address will not be published. Required fields are marked *