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.


Leave a Reply

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