title: Entity Framework TryUpdateModel Child Objects?
body: <p>I know most of you will suggest that I should use ViewModels specific to the form I am using, but I am curious as to why my child object is not binding on TryUpdateModel.</p>
  
  <pre><code>@using (Html.BeginForm()) {
      @Html.ValidationSummary(true)
      &lt;fieldset&gt;
          &lt;legend&gt;User&lt;/legend&gt;
  
          @Html.HiddenFor(model =&gt; model.UserId)
      @Html.HiddenFor(model =&gt; model.PrimaryAddress.AddressId)
      &lt;div class="editor-label"&gt;
              @Html.LabelFor(model =&gt; model.PrimaryAddress.FirstName)
          &lt;/div&gt;
          &lt;div class="editor-field"&gt;
              @Html.EditorFor(model =&gt; model.PrimaryAddress.FirstName)
              @Html.ValidationMessageFor(model =&gt; model.PrimaryAddress.FirstName)
          &lt;/div&gt;
  
          &lt;div class="editor-label"&gt;
              @Html.LabelFor(model =&gt; model.PrimaryAddress.LastName)
          &lt;/div&gt;
          &lt;div class="editor-field"&gt;
              @Html.EditorFor(model =&gt; model.PrimaryAddress.LastName)
              @Html.ValidationMessageFor(model =&gt; model.PrimaryAddress.LastName)
          &lt;/div&gt;
  
          &lt;div class="editor-label"&gt;
              @Html.LabelFor(model =&gt; model.UserName)
          &lt;/div&gt;
          &lt;div class="editor-field"&gt;
              @Html.EditorFor(model =&gt; model.UserName)
              @Html.ValidationMessageFor(model =&gt; model.UserName)
          &lt;/div&gt;
  
          &lt;div class="editor-label"&gt;
              @Html.LabelFor(model =&gt; model.Email)
          &lt;/div&gt;
          &lt;div class="editor-field"&gt;
              @Html.EditorFor(model =&gt; model.Email)
              @Html.ValidationMessageFor(model =&gt; model.Email)
          &lt;/div&gt;
  
          &lt;div class="editor-label"&gt;
              @Html.LabelFor(model =&gt; model.IsApproved)
          &lt;/div&gt;
          &lt;div class="editor-field"&gt;
              @Html.EditorFor(model =&gt; model.IsApproved)
              @Html.ValidationMessageFor(model =&gt; model.IsApproved)
          &lt;/div&gt;
  
          &lt;div class="editor-label"&gt;
              @Html.LabelFor(model =&gt; model.IsEmployee)
          &lt;/div&gt;
          &lt;div class="editor-field"&gt;
              @Html.EditorFor(model =&gt; model.IsEmployee)
              @Html.ValidationMessageFor(model =&gt; model.IsEmployee)
          &lt;/div&gt;
  
          &lt;p&gt;
              &lt;input type="submit" value="Save" /&gt;
          &lt;/p&gt;
      &lt;/fieldset&gt;
  }
  </code></pre>
  
  <p>And the controller code:</p>
  
  <pre><code>[HttpPost]
  public ActionResult Edit(int id, FormCollection form)
  {
      var user = Token.DB.Users.Include("PrimaryAddress").Single(x =&gt; x.UserId == id);
      if (TryUpdateModel(user, new string[] { "UserName", "Email", "IsApproved", "IsEmployee", "PrimaryAddress.FirstName", "PrimaryAddress.LastName" }))
      {
          try
          {
              Token.DB.SaveChanges();
              return RedirectToAction("index");
          }
          catch (Exception ex)
          {
              while (ex.InnerException != null)
                  ex = ex.InnerException;
              if (ex.Message.ToLowerInvariant().Contains("unique"))
                  ModelState.AddModelError("UserName", "UserName already exists");
          }
      }
      return View(User);
  }
  </code></pre>
  
  <p>The code doesn't throw any exceptions, it just doesn't populate the user.PrimaryAddress.FirstName or user.PrimaryAddress.LastName from the form. I'd like to know why?</p>
  
  <p>I already know I can fix the issue with a specific ViewModel and mapping the info in the background. I can also do something like this:</p>
  
  <pre><code>&lt;!-- Edit.cshtml --&gt;
  &lt;div class="editor-field"&gt;
      @Html.EditorFor(model =&gt; model.PrimaryAddress.FirstName, null, "FirstName")
      @Html.ValidationMessageFor(model =&gt; model.PrimaryAddress.FirstName)
  &lt;/div&gt;
  
  &lt;div class="editor-label"&gt;
      @Html.LabelFor(model =&gt; model.PrimaryAddress.LastName)
  &lt;/div&gt;
  &lt;div class="editor-field"&gt;
      @Html.EditorFor(model =&gt; model.PrimaryAddress.LastName, null, "LastName")
      @Html.ValidationMessageFor(model =&gt; model.PrimaryAddress.LastName)
  &lt;/div&gt;
  
  // UsersController.cs
  if (TryUpdateModel(user, new string[] { "UserName", "Email", "IsApproved", "IsEmployee"})
  &amp;&amp; TryUpdateModel(user.PrimaryAddress, new string[] {"FirstName", "LastName" }))
  </code></pre>
  
  <p>So the real question is why isn't it binding in the first example?</p>