ASP.NET The model in MVC3 is self-validating, which is via the System.ComponentModel.DataAnnotations namespace from NET4. All we need to do is add the corresponding Attributes to the attributes of the Model class, and then the MVC3 framework will do the validation for us. I will use the login that comes with the MVC3 project template as an example to explain the validation of the model.

1. Enable Client Validation


Client-side validation is mainly to improve the user experience, and the validation is completed without the web page being brushed back.

The first step is to enable client validation in web.config, which is already available in the template project that comes with MVC3:

<add key="ClientValidationEnabled" value="true"/>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>

Then add these two JavaScripts to the validated View page, note that they depend on jQuery:

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

There are two types of verification messages to be displayed, one is ValidationSummary, which can display a summary of validation messages, including the messages returned from background actions.

@Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.")

The other is the verification message of the HTML control corresponding to each attribute in the model:

@Html.ValidationMessageFor(m => m.UserName)

2. Add Verification Attributes to the Model


The login model class that comes with the MVC3 project template is as follows:

public class LogOnModel
{
    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [Display(Name = "Remember me?")]
    public bool RememberMe { get; set; }
}

Compared to a normal C# class, we find that each property is marked with square brackets "[]". Among them, [Required] is a type of validation attribute, while [Display] and [DataType] are used to display the corresponding HTML code, which is beyond the scope of this article.

In addition to Required, we can also add other useful validation tags to the Model. Here's a more complete list:

Validation attributes that can be added to the Model class

1. Required fields

[Required]
public string FirstName { get; set; }

2. Field length

Up to n characters:

[StringLength(160)]
public string FirstName { get; set; }

At least n characters are required:

[StringLength(160, MinimumLength=3)]
public string FirstName { get; set; }

3. Regular expression

[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]
public string Email { get; set; }

4. Range

[Range(35,44)]
public int Age { get; set; }

with decimal

[Range(typeof(decimal), "0.00", "49.99")]
public decimal Price { get; set; }

5. Server side validation

[Remote("CheckUserName", "Account")]
public string UserName { get; set; }

Then specify a CheckUserName method in the AccountController:  

public JsonResult CheckUserName(string username)
{
    var result = Membership.FindUsersByName(username).Count == 0;
    return Json(result, JsonRequestBehavior.AllowGet);
}

6. Compare

[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}")]
public string Email { get; set; }

[Compare("Email")]
public string EmailConfirm { get; set; }

7. Customize the error message

Regular expression:

[RegularExpression(@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}", ErrorMessage="Email doesn’t look like a valid email address.")]
public string Email { get; set; }

Plain text:

[Required(ErrorMessage="Your last name is required")]
[StringLength(160, ErrorMessage="Your last name is too long")]
public string LastName { get; set; }

Placeholders:

[Required(ErrorMessage="Your {0} is required.")]
[StringLength(160, ErrorMessage="{0} is too long.")]
public string LastName { get; set; }

3. How to Write Backend Actions


There are two things to do in an action: to determine whether the ModelState is valid or not, and to add an error message. The following login actions are provided for the MVC3 template:

[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
    if (ModelState.IsValid)
    {
        if (Membership.ValidateUser(model.UserName, model.Password))
        {
            FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
            if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }
        }
        else
        {
            ModelState.AddModelError("", "The user name or password provided is incorrect.");
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

[HttpPost] means that this Action can only be called by the POST action, which is to cooperate with the form in the View, because the FORM ACTION is POST (of course, it can also be GET), but this is beyond the scope of this article.

if (ModelState.IsValid) is important, if nothing else, i.e. the client browser does not have JavaScript turned off, and the client is not a hacker (the hacker may impersonate the POST through some tool), then the Model that POST to the Action through the normal channel should be IsValid. Of course, an important principle of programming is not to trust the user's input, so we need to judge ModelState.IsValid again.

ModelState.AddModelError returns an error message to the View, which is finally displayed with @Html.ValidationSummary.