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.
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...
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 ;)
This Model:
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; }
}
This view (the "textfield" classes are needed for styling):
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<div class="form-item-right">
@Html.ValidationMessageFor(model => model.FirstName, "First Name is required.")
@Html.TextBoxFor(model => model.FirstName, new { @class = "textfield" })
@Html.LabelFor(model => model.FirstName, "First Name")
</div>
<div class="form-item-right">
@Html.ValidationMessageFor(model => model.LastName)
@Html.TextBoxFor(model => model.LastName, new { @class = "textfield" })
@Html.LabelFor(model => model.LastName, "Last Name")
</div>
<div class="form-item-right">
@Html.ValidationMessageFor(model => model.Email)
@Html.TextBoxFor(model => model.Email, new { @class = "textfield" })
@Html.LabelFor(model => model.Email, "Email Address")
</div>
<div class="form-item-right">
@Html.ValidationMessageFor(model => model.Password)
@Html.PasswordFor(model => model.Password, new { @class = "textfield" })
@Html.LabelFor(model => model.Password, "Password")
</div>
<div class="form-item-right">
@Html.ValidationMessageFor(model => model.ConfirmPassword)
@Html.PasswordFor(model => model.ConfirmPassword, new { @class = "textfield" })
@Html.LabelFor(model => model.ConfirmPassword, "Confirm")
</div>
<div class="form-item-right">
<input type="submit" value="Sign Up!" class="buttonSignUp"/>
</div>
}
This results in markup like:
<span class="field-validation-valid" data-valmsg-for="FirstName" data-valmsg-replace="false">First Name is required.</span>
<input class="textfield" data-val="true" data-val-required="The FirstName field is required." id="FirstName" name="FirstName" value="" type="text">
<label for="FirstName">First Name</label>
These scripts included via a Layout view:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js") "type="text/javascript"></script>
And this in web.config:
<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
Controller code for completeness:
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);
}
}
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).
What's wrong?
Edit to include resulting markup from the view.