Performing client-side validation in MVC4 View against ViewModel
asp.net-mvc, asp.net-mvc-4, c#, client-side-validation, validation
Solution
From my (learning) point of view, the correct answer should be:
Explanation:
Validation of common attributes is done by MVC4 automatically when jQuery Unobtrustive Validator is loaded into the page, otherwise only server-side validation is performed.
Most, if not all of MVC4 `ValidationAttribute`s implement `IClientValidation`. This interface wraps jQuery Validator validation functions in server-side code. It's hard to explain how exactly it works, but saying that this interface returns the name of the client-side function (either provided by jQuery distribution or implemented by user), while basically wrong at least gives the idea to a novice user trying to understand how validation works.
Answer:
Continue using data-driven model/viewmodel annotations. Check if NuGet package jQuery Unobtrusive Validation is loaded in the page, then implement `IClientValidation` as needed (I found a tutorial here about multiple errors), fields are validated automatically.
Problem
I would like to know what is the best approach to handle client-side, javascript or jQuery driven validation of MVC4 fields against attributes placed on a ViewModel's fields. First, let's pick the example. A login creation screen for Administrators shown the first time the application starts (just not to say to the site owner "use admin/admin as login the first time"). ViewModel: ``` public class AdministratorViewModel : AbstractViewModel { [Required] [Display(ResourceType = typeof(ManageAdminsViewModelResources), Name = "lblUsername")] public string Username { get; set; } [Required] [Display(ResourceType = typeof(ManageAdminsViewModelResources), Name = "lblEmailAddress")] [EmailAddress] public string EmailAddress { get; set; } [Required] [Display(ResourceType = typeof(ManageAdminsViewModelResources), Name = "lblPassword")] [AdminPassword] public string Password { get; set; } [Required] [Display(ResourceType = typeof(ManageAdminsViewModelResources), Name = "lblPasswordConfirm")] [Compare("Password")] public string PasswordConfirm { get; set; } [Display(ResourceType = typeof(ManageAdminsViewModelResources), Name = "lblLastLogin")] public DateTime? LastLogin { get; set; } [Display(ResourceType = typeof(ManageAdminsViewModelResources), Name = "lblPasswordExpiry")] public DateTime? PasswordExpiry { get; set; } [Display(ResourceType = typeof(ManageAdminsViewModelResources), Name = "lblBlocked")] public bool Blocked { get; set; } } ``` Partial view (only a few fields needed when creating the first admin) ``` @using (Html.BeginForm()) { @Html.ValidationSummary(false) @Html.AntiForgeryToken() <fieldset> <legend>@ManageAdminsViewResources.legendCreateAdmin</legend> <div class="desktoptile"> @Html.LabelFor(m=>m.Username) @Html.EditorFor(m => m.Username) @Html.ValidationMessageFor(m => m.Username) </div> <div class="desktoptile"> @Html.LabelFor(m=>m.Password) @Html.PasswordFor(m => m.Password) @Html.ValidationMessageFor(m => m.Password) </div> <div class="desktoptile"> @Html.LabelFor(m=>m.PasswordConfirm) @Html.PasswordFor(m => m.PasswordConfirm) @Html.ValidationMessageFor(m => m.PasswordConfirm) </div> <div class="desktoptile"> @Html.LabelFor(m=>m.EmailAddress) @Html.EditorFor(m => m.EmailAddress) @Html.ValidationMessageFor(m => m.EmailAddress) </div> <input type="submit" value="@ManageAdminsViewResources.btnCreate"/> </fieldset> } ``` Controller ``` [AllowAnonymous] [HttpPost] [ValidateAntiForgeryToken] public ActionResult CreateFirst(AdministratorViewModel viewModel) { if (!ModelState.IsValid) return View(viewModel); [...................] ``` Currently If I enter an invalid email address, an empty password, etc. in the form and hit Submit I'm correctly notified of the errors. Ok, let's go on What I want Since I'm doing a Metro-stylish design, I would like that every time the user unfocuses a text box validation for that field occurs. Writing hard-coded jQuery fragments is not the best option. I would like a data-driven approach, possibly embedded in MVC4 which I'm currently learning. So, given a ViewModel with standard and custom attributes (for which, no matter what, a little Javascript is required, think about the `Org.Zighinetto.AdminPasswordAttribute` that checks password complexity), how do I enforce client-side validation the most unobtrusive way, without specifying client-side tags on each and every html tag and writing the least possible amount of code? Is still there any secret in ASP.NET MVC 4 validation that I have to unhide?