title: ASP.net MVC DropDownList value used to Create new object
body: <p>This seems to be a pretty trivial problem that I have been stuck on for about an hour, and I don't understand what I'm doing wrong.</p>
  
  <p>I have a ViewModel:</p>
  
  <pre><code>public class SongFormViewModel
      {
          public Song Song { get; set; }
          public SelectList AlbumList { get; set; }
  
          public SongFormViewModel(Song song, IQueryable&lt;Album&gt; albumList)
          {
              Song = song;
              AlbumList = new SelectList(albumList, "AlbumId", "Title", song.AlbumId);  
          }
      }
  </code></pre>
  
  <p>I have a Create view:</p>
  
  <pre><code>&lt;%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&lt;NightSpot.Models.SongFormViewModel&gt;" %&gt;
  
  &lt;asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"&gt;
      Create
  &lt;/asp:Content&gt;
  
  &lt;asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"&gt;
  
      &lt;h2&gt;Create&lt;/h2&gt;
  
      &lt;%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %&gt;
  
      &lt;% using (Html.BeginForm()) {%&gt;
  
          &lt;fieldset&gt;
              &lt;legend&gt;Fields&lt;/legend&gt;
              &lt;p&gt;
                  &lt;label for="AlbumId"&gt;AlbumId:&lt;/label&gt;
                  &lt;%= Html.DropDownList("AlbumId", Model.AlbumList) %&gt;
                  &lt;%= Html.ValidationMessage("AlbumId", "*") %&gt;
              &lt;/p&gt;
              &lt;p&gt;
                  &lt;label for="Title"&gt;Title:&lt;/label&gt;
                  &lt;%= Html.TextBox("Title") %&gt;
                  &lt;%= Html.ValidationMessage("Title", "*") %&gt;
              &lt;/p&gt;
              &lt;p&gt;
                  &lt;label for="TrackNumber"&gt;TrackNumber:&lt;/label&gt;
                  &lt;%= Html.TextBox("TrackNumber") %&gt;
                  &lt;%= Html.ValidationMessage("TrackNumber", "*") %&gt;
              &lt;/p&gt;
              &lt;p&gt;
                  &lt;input type="submit" value="Create" /&gt;
              &lt;/p&gt;
          &lt;/fieldset&gt;
  
      &lt;% } %&gt;
  
      &lt;div&gt;
          &lt;%=Html.ActionLink("Back to List", "Index") %&gt;
      &lt;/div&gt;
  
  &lt;/asp:Content&gt;
  </code></pre>
  
  <p>And I have a SongsController Create method:</p>
  
  <pre><code>        //
          // POST: /Songs/Create
  
          [AcceptVerbs(HttpVerbs.Post)]
          public ActionResult Create(Song song)
          {
              if (ModelState.IsValid)
              {
                  try
                  {
                      repository.Add(song);
                      repository.Save();
  
                      return RedirectToAction("Details", new { id = song.SongId });
                  }
                  catch
                  {
                      ModelState.AddRuleViolations(song.GetRuleViolations());
                  }
              }
  
              return View(new SongFormViewModel(song, repository.FindAllAlbums()));
          }
  </code></pre>
  
  <p>When I navigate to the /Songs/Create URL I see the expected UI. My drop down list contains a list of all valid Albums in my database (from the Albums table), and I have validated that each AlbumId is the value, and each Title is the Text. Great.</p>
  
  <p>So now when I go to fill out my form and hit "Save", I get an error telling me that I need to select an Album. When I step through the debugger in Visual Web Developer, I see that the Title &amp; Track Number are being populated correctly, but my Album object is NULL, and AlbumId is still 0. Any ideas?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Taking Matt's advice, I updated my SongsController to use a SongFormViewModel instead of a Song. Here's the new controller:</p>
  
  <pre><code>        //
          // POST: /Songs/Create
  
          [AcceptVerbs(HttpVerbs.Post)]
          public ActionResult Create(SongFormViewModel song)
          {
              Song newSong = song.Song;
              newSong.AlbumId = (int) song.AlbumList.SelectedValue;
  
              if (ModelState.IsValid)
              {
                  try
                  {
                      repository.Add(newSong);
                      repository.Save();
  
                      return RedirectToAction("Details", new { id = song.Song.SongId });
                  }
                  catch
                  {
                      ModelState.AddRuleViolations(song.Song.GetRuleViolations());
                  }
              }
  
              return View(new SongFormViewModel(newSong, repository.FindAllAlbums()));
          }
  </code></pre>
  
  <p>I fired up my /Songs/Create URL and got a message saying SongFormViewModel required a parameterless constructor. </p>
  
  <p>So I made one. </p>
  
  <p>When I re-ran the /Songs/Create URL I got an "Object reference not set to an instance of an object" exception on this line in my SongsController:</p>
  
  <pre><code>Line 93:             newSong.AlbumId = (int) song.AlbumList.SelectedValue;
  </code></pre>
  
  <p>Ideas?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>OK, so I updated my view per Matt's suggestion of prefixing the fields with "Song":</p>
  
  <pre><code>&lt;%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&lt;NightSpot.Models.SongFormViewModel&gt;" %&gt;
  
  &lt;asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"&gt;
      Create
  &lt;/asp:Content&gt;
  
  &lt;asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"&gt;
  
      &lt;h2&gt;Create&lt;/h2&gt;
  
      &lt;%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %&gt;
  
      &lt;% using (Html.BeginForm()) {%&gt;
  
          &lt;fieldset&gt;
              &lt;legend&gt;Fields&lt;/legend&gt;
              &lt;p&gt;
                  &lt;label for="Song.AlbumId"&gt;AlbumId:&lt;/label&gt;
                  &lt;%= Html.DropDownList("Song.AlbumId", Model.AlbumList) %&gt;
                  &lt;%= Html.ValidationMessage("Song.AlbumId", "*") %&gt;
              &lt;/p&gt;
              &lt;p&gt;
                  &lt;label for="Song.Title"&gt;Title:&lt;/label&gt;
                  &lt;%= Html.TextBox("Song.Title") %&gt;
                  &lt;%= Html.ValidationMessage("Song.Title", "*") %&gt;
              &lt;/p&gt;
              &lt;p&gt;
                  &lt;label for="Song.TrackNumber"&gt;TrackNumber:&lt;/label&gt;
                  &lt;%= Html.TextBox("Song.TrackNumber") %&gt;
                  &lt;%= Html.ValidationMessage("Song.TrackNumber", "*") %&gt;
              &lt;/p&gt;
              &lt;p&gt;
                  &lt;input type="submit" value="Create" /&gt;
              &lt;/p&gt;
          &lt;/fieldset&gt;
  
      &lt;% } %&gt;
  
      &lt;div&gt;
          &lt;%=Html.ActionLink("Back to List", "Index") %&gt;
      &lt;/div&gt;
  
  &lt;/asp:Content&gt;
  </code></pre>
  
  <p>The behavior is, unfortunately, the same. Null SelectedValue and an empty Song object.</p>