title: MVC3 client side validation -- what am I missing?
body: <p>I've googled, looked at blogs, checked out multiple answers here on SO... when I enable "Client Side Validation" in my MVC3 app, validation only takes place on the server, not the client -- my forms post with required text inputs that do not have values, only to be bounced at the server. </p>
  
  <p>Full disclosure: I've never gotten this to work consistently and completely in any of the 3 MVC projects I've done so far. I'm convinced I'm missing something fundamental here, since the vast majority of the examples and how-to's I find carry "This article refers to beta release" disclaimers...</p>
  
  <p>This is usually the point where I get frustrated and rip out all the "everything client side must be indirect and magic because we're afraid to have developers write javascript" garbage and just use jquery.validation directly, but I figured I'd try posting here to see if I'm missing something fundamental ... like I usually seem to be ;)</p>
  
  <p>This Model:</p>
  
  <pre><code>public class RegisterModel
  {
      [Required]
      public string FirstName { get; set; }
      [Required]
      public string LastName { get; set; }
      [Required]
      public string Email { get; set; }
      [Required]
      public string Password { get; set; }
      [Required]
      public string ConfirmPassword { get; set; }
  }
  </code></pre>
  
  <p>This view (the "textfield" classes are needed for styling):</p>
  
  <pre><code>@using (Html.BeginForm()) {
      @Html.ValidationSummary(true)
      &lt;div class="form-item-right"&gt;
              @Html.ValidationMessageFor(model =&gt; model.FirstName, "First Name is required.")
              @Html.TextBoxFor(model =&gt; model.FirstName, new { @class = "textfield" })
              @Html.LabelFor(model =&gt; model.FirstName, "First Name")
  
  
          &lt;/div&gt;
  
          &lt;div class="form-item-right"&gt;
              @Html.ValidationMessageFor(model =&gt; model.LastName)
              @Html.TextBoxFor(model =&gt; model.LastName, new { @class = "textfield" })
              @Html.LabelFor(model =&gt; model.LastName, "Last Name")
          &lt;/div&gt;
  
          &lt;div class="form-item-right"&gt;
              @Html.ValidationMessageFor(model =&gt; model.Email)
              @Html.TextBoxFor(model =&gt; model.Email, new { @class = "textfield" })
              @Html.LabelFor(model =&gt; model.Email, "Email Address")
  
          &lt;/div&gt;
  
          &lt;div class="form-item-right"&gt;
              @Html.ValidationMessageFor(model =&gt; model.Password)
              @Html.PasswordFor(model =&gt; model.Password, new { @class = "textfield" })
              @Html.LabelFor(model =&gt; model.Password, "Password")
  
          &lt;/div&gt;
  
          &lt;div class="form-item-right"&gt;
              @Html.ValidationMessageFor(model =&gt; model.ConfirmPassword)
              @Html.PasswordFor(model =&gt; model.ConfirmPassword, new { @class = "textfield" })
              @Html.LabelFor(model =&gt; model.ConfirmPassword, "Confirm")
  
          &lt;/div&gt;
  
          &lt;div class="form-item-right"&gt;
              &lt;input type="submit" value="Sign Up!" class="buttonSignUp"/&gt;
          &lt;/div&gt;
  
  
  
  }
  </code></pre>
  
  <p>This results in markup like:</p>
  
  <pre><code>            &lt;span class="field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="false"&gt;First Name is required.&lt;/span&gt;
              &lt;input class="textfield" data-val="true" data-val-required="The FirstName field is required." id="FirstName" name="FirstName" value="" type="text"&gt;
              &lt;label for="FirstName"&gt;First Name&lt;/label&gt;
  </code></pre>
  
  <p>These scripts included via a Layout view:</p>
  
  <pre><code>&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"&gt;&lt;/script&gt;
  &lt;script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"&gt;&lt;/script&gt;
  &lt;script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js") "type="text/javascript"&gt;&lt;/script&gt;
  </code></pre>
  
  <p>And this in web.config:</p>
  
  <pre><code>&lt;add key="ClientValidationEnabled" value="true"/&gt;
  &lt;add key="UnobtrusiveJavaScriptEnabled" value="true"/&gt;
  </code></pre>
  
  <p>Controller code for completeness:</p>
  
  <pre><code>    public ActionResult Candidate()
      {
          return View();
      }
  
      [HttpPost]
      public ActionResult Candidate(RegisterModel model)
      {
          if (ModelState.IsValid)
          {
              //complete the registration
  
              return View("Confirm", new ConfirmationModel { Email = model.Email, FirstName = model.FirstName });   
          }
          else
          {
              return View(model);
          }
      }
  </code></pre>
  
  <p>All results in a view that does no validation on the client side. The form posts with no fields entered at all. Validation only takes place at the server (which works correctly FWIW).</p>
  
  <p>What's wrong?</p>
  
  <p>Edit to include resulting markup from the view.</p>