title: How to get's the model metadata from an IEnumerable?
body: <p>I have GridView in MVC which is constructed in the following way:</p>
  
  <p>@model IEnumerable</p>
  
  <pre><code>@(Html.GridFor()
        .WithName("PageOverviewGrid")
        .WithColumns(model =&gt;
        {
            model.Bind(x =&gt; x.Name);
            model.Bind(x =&gt; x.DateCreated);
            model.Bind(x =&gt; x.DateUpdated);
        })
  )
  </code></pre>
  
  <p>What you see above is that I'm constructing a grid of my model, which is an IEnumerable and I bind 3 columns to it.</p>
  
  <p>The code of my HtmlHelper is the following:</p>
  
  <pre><code>/// &lt;summary&gt;
  ///     Provides a way to extend the &lt;see cref="HtmlHelper" /&gt;.
  /// &lt;/summary&gt;
  public static class HtmlHelperExtensions
  {
      #region Grid
  
      /// &lt;summary&gt;
      ///     Constructs a grid for a given model by using a fluent API.
      /// &lt;/summary&gt;
      /// &lt;typeparam name="TModel"&gt;The type of the model that is bound to the grid.&lt;/typeparam&gt;
      /// &lt;param name="htmlHelper"&gt;The &lt;see cref="HtmlHelper" /&gt; which is used to create the grid.&lt;/param&gt;
      /// &lt;returns&gt;An &lt;see cref="IGridBuilder{TModel}" /&gt; that is used to construct the grid.&lt;/returns&gt;
      public static IGridBuilder&lt;TModel&gt; GridFor&lt;TModel&gt;(this HtmlHelper&lt;IEnumerable&lt;TModel&gt;&gt; htmlHelper)
      {
          return new GridBuilder&lt;TModel&gt;(htmlHelper);
      }
  
      #endregion
  }
  </code></pre>
  
  <p>I'll return an inteface in this method to allow the construction through a fluent API.
  The code of that interface is the following:</p>
  
  <pre><code>/// &lt;summary&gt;
  ///     When implemented on a class, this class acts as an &lt;see cref="IHtmlString" /&gt; that can construct a grid by using a
  ///     fluent API.
  /// &lt;/summary&gt;
  /// &lt;typeparam name="TModel"&gt;The type of the model that is bound to the grid.&lt;/typeparam&gt;
  public interface IGridBuilder&lt;TModel&gt; : IHtmlString
  {
      #region Properties
  
      /// &lt;summary&gt;
      ///     Gets the name of the &lt;see cref="IGridBuilder{TModel}" /&gt;.
      ///     The outer div of the grid will have an id that matches this name.
      /// &lt;/summary&gt;
      string Name { get; }
  
      /// &lt;summary&gt;
      ///     The &lt;see cref="HtmlHelper" /&gt; that is used to build the grid.
      /// &lt;/summary&gt;
      HtmlHelper HtmlHelper { get; }
  
      #endregion
  
      #region Methods
  
      /// &lt;summary&gt;
      ///     Sets the name of the &lt;see cref="IGridBuilder{TModel}" /&gt;.
      /// &lt;/summary&gt;
      /// &lt;param name="name"&gt;The name that the &lt;see cref="IGridBuilder{TModel}" /&gt; should have.&lt;/param&gt;
      /// &lt;returns&gt;An &lt;see cref="IGridBuilder{TModel}" /&gt; that is used to construct the grid.&lt;/returns&gt;
      IGridBuilder&lt;TModel&gt; WithName(string name);
  
      /// &lt;summary&gt;
      ///     Set the columns of the model that should be bound to grid.
      /// &lt;/summary&gt;
      /// &lt;param name="bindAllColumns"&gt;The action that will bind all the columns.&lt;/param&gt;
      /// &lt;returns&gt;An &lt;see cref="IGridBuilder{TModel}" /&gt; that is used to construct the grid.&lt;/returns&gt;
      IGridBuilder&lt;TModel&gt; WithColumns(Action&lt;IGridBuilder&lt;TModel&gt;&gt; bindAllColumns);
  
      /// &lt;summary&gt;
      ///     Binds an column to the grid.
      /// &lt;/summary&gt;
      /// &lt;typeparam name="TItem"&gt;The type of the column on which to bind the items.&lt;/typeparam&gt;
      /// &lt;param name="propertySelector"&gt;The functional that will bind the control to the grid.&lt;/param&gt;
      void Bind&lt;TItem&gt;(Expression&lt;Func&lt;TModel, TItem&gt;&gt; propertySelector);
  
      #endregion
  }
  </code></pre>
  
  <p>Then I have, off course, the implementation of it:</p>
  
  <pre><code>/// &lt;summary&gt;
  ///     An implementation of the &lt;see cref="IGridBuilder{TModel}" /&gt; that is used to build a grid.
  /// &lt;/summary&gt;
  /// &lt;typeparam name="TModel"&gt;The type of the model that is bound to the grid.&lt;/typeparam&gt;
  public class GridBuilder&lt;TModel&gt; : IGridBuilder&lt;TModel&gt; 
  {
      #region Constructors
  
      /// &lt;summary&gt;
      ///     Creates a new instance of the &lt;see cref="GridBuilder{TModel}" /&gt;.
      /// &lt;/summary&gt;
      /// &lt;param name="htmlHelper"&gt;The &lt;see cref="HtmlHelper{TModel}" /&gt; that is used to render this one.&lt;/param&gt;
      public GridBuilder(HtmlHelper&lt;IEnumerable&lt;TModel&gt;&gt; htmlHelper)
      {
          HtmlHelper = htmlHelper;
          properties = new Dictionary&lt;string, List&lt;string&gt;&gt;();
      }
  
      #endregion
  
      #region Properties
  
      /// &lt;summary&gt;
      ///     A &lt;see cref="List{TKey}" /&gt; that conains the names of the property and the display name that belongs
      ///     to the property.
      /// &lt;/summary&gt;
  
      public readonly Dictionary&lt;string, List&lt;string&gt;&gt; properties;
  
      #endregion
  
      #region IGridBuilder Members
  
      /// &lt;summary&gt;
      ///     Gets the name of the &lt;see cref="IGridBuilder{TModel}" /&gt;.
      ///     The outer div of the grid will have an id that matches this name.
      /// &lt;/summary&gt;
      public string Name { get; private set; }
  
      /// &lt;summary&gt;
      ///     The &lt;see cref="HtmlHelper" /&gt; that is used to build the grid.
      /// &lt;/summary&gt;
      public HtmlHelper HtmlHelper { get; private set; }
  
      /// &lt;summary&gt;
      ///     Sets the name of the &lt;see cref="IGridBuilder{TModel}" /&gt;.
      /// &lt;/summary&gt;
      /// &lt;param name="name"&gt;The name that the &lt;see cref="IGridBuilder{TModel}" /&gt; should have.&lt;/param&gt;
      /// &lt;returns&gt;An &lt;see cref="IGridBuilder{TModel}" /&gt; that is used to construct the grid.&lt;/returns&gt;
      public IGridBuilder&lt;TModel&gt; WithName(string name)
      {
          Name = name;
          return this;
      }
  
      /// &lt;summary&gt;
      ///     Binds an column to the grid.
      /// &lt;/summary&gt;
      /// &lt;typeparam name="TItem"&gt;The type of the column on which to bind the items.&lt;/typeparam&gt;
      /// &lt;param name="propertySelector"&gt;The functional that will bind the control to the grid.&lt;/param&gt;
      public void Bind&lt;TItem&gt;(Expression&lt;Func&lt;TModel, TItem&gt;&gt; propertySelector)
      {
          string name = ExpressionHelper.GetExpressionText(propertySelector);
          name = HtmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
  
          ModelMetadata metadata =
              ModelMetadataProviders.Current.GetMetadataForProperty(() =&gt; Activator.CreateInstance&lt;TModel&gt;(),
                  typeof(TModel), name);
  
          // Get's the name to display on the column in grid. The Display attribute is used if present, otherwise the name of the property is used.
          string displayName = string.IsNullOrEmpty(metadata.DisplayName)
              ? metadata.PropertyName
              : metadata.DisplayName;
  
          var items = (from TModel entity in HtmlHelper.ViewData.Model as IEnumerable select propertySelector.Compile().Invoke(entity).ToString()).ToList();
  
          properties.Add(displayName, items);
      }
  
      /// &lt;summary&gt;
      ///     Set the columns of the model that should be bound to grid.
      /// &lt;/summary&gt;
      /// &lt;param name="bindAllColumns"&gt;The action that will bind all the columns.&lt;/param&gt;
      /// &lt;returns&gt;An &lt;see cref="IGridBuilder{TModel}" /&gt; that is used to construct the grid.&lt;/returns&gt;
      public IGridBuilder&lt;TModel&gt; WithColumns(Action&lt;IGridBuilder&lt;TModel&gt;&gt; bindAllColumns)
      {
          bindAllColumns(this);
          return this;
      }
  
      #endregion
  
      #region IHtmlString Members
  
      /// &lt;summary&gt;
      ///     Returns an HTML-encoded string.
      /// &lt;/summary&gt;
      /// &lt;returns&gt;Returns an HTML-encoded string.&lt;/returns&gt;
      public string ToHtmlString()
      {
          var output = new StringBuilder();
  
          BaseElementBuilder parentBuilder = DivFactory.DivElement().WithCssClass("gridHolder v-scroll").WithId(Name);
          BaseElementBuilder headerBuilder = DivFactory.DivElement().WithCssClass("header");
  
          output.Append(parentBuilder.ToString(TagRenderMode.StartTag));
          output.Append(headerBuilder.ToString(TagRenderMode.StartTag));
  
          var index = 0;
          foreach (
             var propertyBuilder in
                  properties.Select(
                      property =&gt;
                          (index == 0)
                              ? DivFactory.DivElement().WithCssClass("inline").WithInnerHtml(property.Key)
                              : DivFactory.DivElement()
                                  .WithCssClass("inline fixed right")
                                  .WithInnerHtml(property.Key)))
          {
              output.Append(propertyBuilder);
              index += 1;
          }
  
          output.Append(headerBuilder.ToString(TagRenderMode.EndTag));
  
          for (int i = 0; i &lt; properties.First().Value.Count(); i++)
          {
              BaseElementBuilder rowBuilder = DivFactory.DivElement().WithCssClass("row");
              output.Append(rowBuilder.ToString(TagRenderMode.StartTag));
  
              BaseElementBuilder iconBuilder = DivFactory.DivElement().WithCssClass("inline icon").WithInnerHtml("&lt;img src=\"~/Resources/Icons/Grid/Pages/Page.png\" /&gt;");
              output.Append(iconBuilder.ToString(TagRenderMode.StartTag));
              output.Append(iconBuilder.ToString(TagRenderMode.EndTag));
  
              int loopIndex = 0;
              foreach (var propertyBuilder in properties)
              {
                  var value = propertyBuilder.Value[i];
                  BaseElementBuilder propertyConstructor = (loopIndex == 0)
                      ? DivFactory.DivElement().WithCssClass("inline").WithInnerHtml(value)
                      : DivFactory.DivElement().WithCssClass("inline fixed right").WithInnerHtml(value);
  
                  loopIndex += 1;
  
                  output.Append(propertyConstructor.ToString(TagRenderMode.Normal));
              }
  
              output.Append(rowBuilder.ToString(TagRenderMode.EndTag));
          }
  
          output.Append(parentBuilder.ToString(TagRenderMode.EndTag));
  
          return output.ToString();
      }
  
      #endregion
  }
  </code></pre>
  
  <p>And it's in this implementation that I'm concerned about a little thing:</p>
  
  <ol>
  <li>In the function <strong>public void Bind(Expression> propertySelector)</strong> I'm using reflection to get the metadata of the model. Not too sure if this is the correct way.</li>
  </ol>