title: How can I get the metadata of the items in a collection in razor view-engine?
body: <p>I have a project written in <code>C#</code> on the top on ASP.NET MVC 5 framework. I am trying to decouple my views from my view model so I can make my views reusable. With the heavy use of <code>EditorTemplates</code> I am able to create all of my standard views (i.e create, edit and details) by evaluating the <code>ModelMetadata</code> and the data-annotation-attributes for each property on the model, then render the page. The only thing that I am puzzled with is how to render the <code>Index</code> view.</p>
  
  <p>My index view typically accepts an <code>IEnumerable&lt;object&gt;</code> or <code>IPagedList&lt;object&gt;</code> collection. In my view, I want to be able to evaluate the ModelMetadata of a each <code>object</code>/record in the collection to determine if a property on the <code>object</code> should be displayed or not.</p>
  
  <p>In another words my view-model will look something like this</p>
  
  <pre><code>public class DisplayPersonViewModel
  {
      public int Id{ get; set; }
  
      [ShowOnIndexView]
      public string FirstName { get; set; }
  
      [ShowOnIndexView]
      public string LastName { get; set; }
  
      [ShowOnIndexView]
      public int? Age { get; set; }
  
      public string Gender { get; set; }
  }
  </code></pre>
  
  <p>Then my <code>Index.cshtml</code> view will accepts <code>IPagedList&lt;DisplayPersonViewModel&gt;</code> for each record in the collection, I want to display the value of the property that is decorated with <code>ShowOnIndexView</code> attribute.</p>
  
  <p>Typically I would be able to do that my evaluating the ModelMetadata in my view with something like this</p>
  
  <pre><code>@model IPagedList&lt;object&gt;
  @{
  var elements = ViewData.ModelMetadata.Properties.Where(metadata =&gt; !metadata.IsComplexType &amp;&amp; !ViewData.TemplateInfo.Visited(metadata))
                                                  .OrderBy(x =&gt; x.Order)
                                                  .ToList();
  }
  
  &lt;tr&gt;
      @foreach(var element in elements)
      {
          var onIndex = element.ContainerType.GetProperty(element.PropertyName)
                               .GetCustomAttributes(typeof(ShowOnIndexView), true)
                               .Select(x =&gt; x as ShowOnIndexView)
                               .FirstOrDefault(x =&gt; x != null);
          if(onIndex == null) 
          {
              continue;
          }
  
          @Html.Editor(element.PropertyName, "ReadOnly")
      }
  &lt;/tr&gt;
  </code></pre>
  
  <p>Then my controller will look something like this</p>
  
  <pre><code>public class PersonController : Controller
  {
          public ActionResult Index()
          {
              // This would be a call to a service to give me a collection with items. but I am but showing the I would pass a collection to my view
              var viewModel = new List&lt;DisplayPersonViewModel&gt;();
  
              return View(viewModel);
          }
  }
  </code></pre>
  
  <p>However the problem with evaluating <code>ModelMetadata</code> for the <code>IPagedList&lt;DisplayPersonViewModel&gt;</code> is that it gives me information about the collection itself not about the generic type or the single model in the collection. In another words, I get info like, total-pages, items-per-page, total-records.... </p>
  
  <p><strong>Question</strong></p>
  
  <p>How can I access the <code>ModelMetadata</code> info for each row in the collection to be able to know which property to display and which not to?</p>