title: MVC and Entity Framework Html.DisplayNameFor with Composite ViewModel
body: <p>I’m fairly comfortable with MVVM using WPF/Silverlight but this is my first attempt at an MVC Web Application…just an fyi for my background.</p>
  
  <p>I’ve created a controller called TestSitesController which was auto generated from from the “Site” model class in my Entity Framework Model (the template that generates the read/write actions and views).  The only thing I modified was in 3 spots there was a default parameter of Guid id = null for some methods.  I just got rid of the “ = null” all works fine.  Here is an example of what I changed</p>
  
  <pre><code>public ActionResult Delete(Guid id = null)
  {
      //....
  }
  </code></pre>
  
  <p>This was changed to</p>
  
  <pre><code>public ActionResult Delete(Guid id)
  {
      //....
  }
  </code></pre>
  
  <p>The Site model is nothing special SiteId, Abbreviation, and DisplayName…trying to keep it as simple as possible for this question. Ok so I run the website and goto htpp://.../TestSites/ and everything works perfectly.</p>
  
  <p>I noticed that all of my views (Create, Delete, Details and Edit) are using an @model MVCWeb.MyEntities.Site which I’m perfectly ok with for now; but in the Index.cshtml view I noticed it was using an </p>
  
  <pre><code>@model IEnumerable&lt;MVCWeb.MyEntities.Site&gt;
  </code></pre>
  
  <p>This works fine for the generated template but I would like to use a “Composite View Model” and maybe this is where I’m trying to mix in my MVVM knowledge but would to stick with that if all possible.  In my mind a Composite View Model is just a Model that is specific towards a view that is composed of 1 or more Entity Models along with additional properties like SelectedSiteId, etc.</p>
  
  <p>So I created a very simple ViewModel called TestSitesViewModel</p>
  
  <pre><code>public class TestSitesViewModel
  {
      //Eventually this will be added to a base ViewModel to get rid
      //of the ViewBag dependencies
      [Display(Name = "Web Page Title")]
      public string WebPageTitle;
  
      public IEnumerable&lt;MVCWeb.MyEntities.Site&gt; Sites;
  
      //Other Entities, IEnumberables, or properties go here
      //Not important for this example
  }
  </code></pre>
  
  <p>Then in my controller I added an action method called IndexWithViewModel</p>
  
  <pre><code>public ActionResult IndexWithViewModel()
  {
      var vm = new TestSitesViewModel();
      vm.WebPageTitle = "Sites With Composite View Model";
      vm.Sites = db.Sites.ToList();
  
      return View(vm);
  }
  </code></pre>
  
  <p>I then made a copy of the Index.cshtml and named it IndexWithModel.cshtml to match my new ActionResult method name.  I changed the top line of</p>
  
  <pre><code>@model IEnumerable&lt;MVCWeb.MyEntities.Site&gt;
  </code></pre>
  
  <p>To</p>
  
  <pre><code>@model MVCWeb.Models.TestSitesViewModel
  </code></pre>
  
  <p>I added this before the table section to test for the DisplayNameFor and the DisplayFor</p>
  
  <pre><code>@Html.DisplayNameFor(model =&gt; model.WebPageTitle)
  &amp;nbsp;
  @Html.DisplayFor(model =&gt; model.WebPageTitle)
  &lt;br /&gt;
  </code></pre>
  
  <p>Changed the </p>
  
  <pre><code>@foreach (var item in Model) {
  </code></pre>
  
  <p>To</p>
  
  <pre><code>@foreach (var item in Model.Sites) {
  </code></pre>
  
  <p>And commented out the tr section that contains all of the table headers for now.  Everything works perfectly except that the @Html.DisplayNameFor is displaying the variable name of “WebPageTitle” instead of using “Web Page Title” as denoted in the Display attribute of the Data Annotation in</p>
  
  <pre><code>[Display(Name = "Web Page Title")]
  public string WebPageTitle;
  </code></pre>
  
  <p>Also if I comment back in the tr section that contains the table header information.  I can not for the life of me figure out what to put in I’ve tried model.Sites.Abbreviation, model.Sites[0].Abbreviation, and various other combinations but get errors.</p>
  
  <pre><code>&lt;tr&gt;
      &lt;th&gt;
          @Html.DisplayNameFor(model =&gt; model.Abbreviation)
      &lt;/th&gt;
      &lt;th&gt;
          @Html.DisplayNameFor(model =&gt; model.DisplayName)
      &lt;/th&gt;
      &lt;th&gt;&lt;/th&gt;
  &lt;/tr&gt;
  </code></pre>
  
  <p>So what should I use there?  I'm not quite sure why model.Sites.Abbreviation doesn't work as Sites is the exact same type that was used as the model in the original Index.cshtml</p>