title: MVC 3 validation messages not shown due ModelState lost after PartialView
body: <p>I have an MVC 3 project where I have 1 view LoginRegister which contains 2 views with forms for login and pre-register. The problem is after incorrectly completing the pre-register form and using PartialView("LoginRegister", loginRegisterViewModel) validation messages aren't displayed due the ModelState being lost. Before reading the next paragraph it's probably best to jump to the <strong>CODE</strong>.</p>
  
  <p>Debugging the PartialView("LoginRegister", loginRegisterViewModel) and stepping into the PreRegister view to the following @Html.ErrorMessageFor(model => model.Email). Where the ModelState does not contain the Email key (see below) and hence doesn't display an error message.</p>
  
  <pre><code>    private static MvcHtmlString ErrorMessageHelper(this HtmlHelper htmlHelper, ModelMetadata modelMetadata, string expression, string validationMessage, IDictionary&lt;string, object&gt; htmlAttributes)
      {
          string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
  
          if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName)) // ModelState contains no keys, e.g. Email not found and a null is returned
          {
              return null; 
          }
  
          // code continues here to render error message
      }
  </code></pre>
  
  <h2>CODE</h2>
  
  <p><strong>ViewModels</strong></p>
  
  <p><strong>LoginRegisterViewModel</strong></p>
  
  <pre><code>namespace Site.ViewModels.Account
  {
      public class LoginRegisterViewModel
      {
          public bool IsDialog { get; set; }
          public PreRegisterViewModel PreRegister { get; set; }
          public QuickLoginViewModel QuickLogin { get; set; }
      }
  }
  </code></pre>
  
  <p><strong>PreRegisterViewModel</strong></p>
  
  <pre><code>using FluentValidation.Attributes;
  using Site.ViewModels.Validators;
  
  namespace Site.ViewModels.Account
  {
      [Validator(typeof(PreRegisterViewModelValidator))]
      public class PreRegisterViewModel
      {
          public string Email { get; set; }
          public string ConfirmEmail { get; set; }
      }
  }
  </code></pre>
  
  <p><strong>Views</strong></p>
  
  <p><strong>LoginRegister</strong></p>
  
  <pre><code>@model Site.ViewModels.Account.LoginRegisterViewModel
  
  @{
      Layout = ViewBag.Layout;
  }
  
  &lt;div id="loginReg" class="mod-loginReg"&gt;
      &lt;h2&gt;Login and Registration&lt;/h2&gt;
      @{Html.RenderPartial("PreRegister", Model.PreRegister, new ViewDataDictionary());}
      @{Html.RenderPartial("QuickLogin", Model.QuickLogin, new ViewDataDictionary());}
  &lt;/div&gt;
  </code></pre>
  
  <p><strong>PreRegister</strong></p>
  
  <pre><code>@using Site.Classes.MVC.Extensions;
  
  @model Site.ViewModels.Account.PreRegisterViewModel
  
  @using (Html.BeginForm("PreRegister", "Account", FormMethod.Post, new { @class = "form-errorContainer" }))
  {
      &lt;div class="mod-loginReg-register"&gt;
          &lt;h3&gt;Register&lt;/h3&gt;
          &lt;p&gt;Please enter your email address to register.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
  
          &lt;div class="mod-loginReg-form"&gt;
              &lt;div class="field-item"&gt;
                  @Html.LabelFor(model =&gt; model.Email)
                  @Html.TextBoxFor(model =&gt; model.Email, new { @maxlength = "255", @class = "Textbox required email" })
                  @Html.ErrorMessageFor(model =&gt; model.Email)
              &lt;/div&gt;
              &lt;div class="field-item"&gt;
                  @Html.LabelFor(model =&gt; model.ConfirmEmail)
                  @Html.TextBoxFor(model =&gt; model.ConfirmEmail, new { @maxlength = "255", @class = "Textbox required email" })
                  @Html.ErrorMessageFor(model =&gt; model.ConfirmEmail)
              &lt;/div&gt;
              &lt;div class="button-group"&gt;
                  @Html.Button("Register", "Register")
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  }
  </code></pre>
  
  <p><strong>AccountController</strong></p>
  
  <pre><code>    [RequireHttps]
      public ActionResult LoginRegister(int showDialog)
      {
          var loginRegisterViewModel = new LoginRegisterViewModel();
  
          if (showDialog == 1)
          {
              ViewBag.Layout = "~/layouts/structure/dialog.cshtml";
              loginRegisterViewModel.IsDialog = true;
          }
          else
          {
              ViewBag.Layout = "~/layouts/structure/2column.cshtml";
          }
  
          return PartialView(loginRegisterViewModel);
      }
  
      [RequireHttps]
      public ActionResult PreRegister()
      {
          return PartialView();
      }
  
      [HttpPost]
      [RequireHttps]
      public ActionResult PreRegister(PreRegisterViewModel model)
      {
          if (ModelState.IsValid)
          {
              return PartialView("PreRegisterComplete");
          }
  
          var loginRegisterViewModel = new LoginRegisterViewModel { PreRegister = model, QuickLogin = new QuickLoginViewModel() };
  
          return PartialView("LoginRegister", loginRegisterViewModel);
      }
  </code></pre>