Validation In Razor Web Pages 2

4.53 (36 votes)

The new release of ASP.NET Web Pages - version 2 - doesn't include many obvious changes, but the most significant one is an enhanced Validation system. A couple of new classes have been introduced, and Web Pages validation now works with the MVC Unobtrusive jQuery validation library. This article explores the new validation system and sees what it brings to the party.

To begin with, it's worth noting that Web Pages v 1.0 style validation still works as it always did. You can still use ModelState to log validation errors and test to see if ModelState.IsValid before processing any user input. Version 2.0 introduces two new classes: ValidationHelper and Validator. The Validator class offers a number of different types of validator:

  • Validator.DateTime()
  • Validator.Decimal()
  • Validator.EqualsTo()
  • Validator.Float()
  • Validator.Integer()
  • Validator.Range()
  • Validator.Regex()
  • Validator.Required()
  • Validator.StringLength()
  • Validator.Url()

These methods result in differing validation being applied to values. The DateTime(), Decimal(), Float(), Integer() and Uri() methods all test for data type. The EqualsTo() method enables you to test to see if the value provided in one field is the same as the value provided in another. This is used commonly when you ask someone to enter their password twice on registration to ensure that they got it right first time. The Range() method tests to see if a value is within a specified range of numbers. The Regex() method takes a regular expression pattern and test to see if the supplied value matches the pattern. You might use this to test if a value is in a valid format for an email address, for example. The Required() method is a nice replacement to the old IsEmpty() test, in that it dictates that the field it is applied to is mandatory. Finally, the StringLength() method enables you to specify a minimum and/or maximum number of characters that will be accepted for any value submitted.

The Validation helper class offers some key methods and properties including the following:

  • Validation.Add()
  • Validation.ClassFor()
  • Validation.For()
  • Validation.IsValid()
  • Validation.RequireField()
  • Validation.RequireFields()

There are two ways of specifying that a form field is mandatory. One is to use the Validation.RequireField() method, and the other is to use the Validation.Add() method:

Validation.RequireField("firstname", "You must provide a first name");
Validation.Add("firstname", Validator.Required("You must provide a first name"));

The RequireField method takes the name of the form field and an optional error message. If you do not supply your own error message, the default one provided by the Web Pages framework is used instead. For required fields, that default error message is "This field is required". The Add method is more wordy in that you must specify the type of validator you want to apply through the Validator class. However, it is more flexible in that you can specify any number of different types of validator:

    Validator.Required("You must provide a first name"), 
    Validator.StringLength(10, 0, "No more than 10 letters")

The RequireFields method provides a means for you to specify multiple fields as mandatory, but you cannot provide tailored error messages for each one. You have to reply on the default error message. Lazy, but if you are developing an Intranet where appearances are not important, you might use this:

Validation.RequireFields("firstname", "lastname", "email");

Here's a sample form that shows a variety of validators applied, and the use of the Validation.IsValid() method to test that all validators passed:

    var result = "";
        Validator.Required("You must provide a first name"), 
        Validator.StringLength(10, 0, "No more than 10 letters")
    Validation.RequireField("lastname", "Gimme your Last name!");
        Validator.Required("URL is required"),
        Validator.Url("Must be a valid web address")
        "Invalid format for an email address")
        Validator.Required("Make sure you say how many you want"),
        Validator.Range(1,4, "Must be between 1 and 4")
    Validation.RequireField("password", "Password cannot be empty");
        Validator.Required("Put your password in here again"),
        Validator.EqualsTo("password", "Must be the same as your password")
        if (Validation.IsValid()) {
            result += "<p>You entered:</p>";
            foreach(string item in Request.Form){
                result += item + ": " + Request[item] + "<br />";
            ModelState.AddFormError("There are some errors with your submission"); 

<!DOCTYPE html>
<html lang="en">

        <link href="~/Content/StyleSheet.css" rel="stylesheet" type="text/css" />
            <legend>Web Pages 2 Validation</legend>
            <form method="post" action="">
                <div class="row">
                <div class="row">
                    <label class="label" for="firstname">First Name:</label>
                    <span><input name="firstname" type="text" value="@Request["firstname"]" /></span>
                <div class="row">
                    <label class="label" for="lastname">Last Name:</label>
                    <span>@Html.TextBox("lastname", Request["lastname"])</span>
                <div class="row">
                    <label class="label" for="birthdate">Birth Date:</label>
                    <span>@Html.TextBox("birthdate", Request["birthdate"])</span>
                <div class="row">
                    <label class="label" for="webaddress">Web Address:</label>
                    <span>@Html.TextBox("webaddress", Request["webaddress"])</span>
                <div class="row">
                    <label class="label" for="email">Email:</label>
                    <span>@Html.TextBox("email", Request["email"])</span>
                <div class="row">
                    <label class="label" for="number">Number Required:</label>
                    <span>@Html.TextBox("number", Request["number"])</span>
                <div class="row">
                    <label class="label" for="password">Password:</label>
                <div class="row">
                    <label class="label" for="password2">Password Again:</label>
                    <span class="label">&nbsp;</span>
                    <span><input type="submit" value="Submit" /></span>

The Html.ValidationSummary() method from Web Pages v 1 is still available and will display general messages that have been applied through the ModelState.AddFormError method, and optionally, all individual field validation error messages if the excludeFieldErrors parameter is set to "false" (as is not the case above). You can see that, along with some other interesting things in the image below, which is the result of submitting the form to the server without entering any values at all:

Individual field validation error messages are rendered using the Html.ValidationMessage() helper, which takes the name of the field to be validated as a parameter. This hasn't changed from v 1. Notice in this example that some of the inputs have a pink background, whereas some others don't. Here is the part of the style sheet that controls the appearance of the inputs:

.validation-summary-errors {
    border: 2px solid #990099;
    color: red;

.field-validation-error {
    color: #990099;

.input-validation-error {
    color: #990099;
    background-color: #ff80ff;
    border-top: 2px solid #990099;
    border-left: 2px solid #990099;

The validation-summary-errors rule is applied to the Html.ValidationSummary output. The field-validation-error style is applied to the individual field error messages, and the input-validation-error class is responsible for styling the actual form inputs when they are associated with a failed validation. However, the firstname field is not styled, even though it clearly failed validation, whereas all others have been styled as a result of failed validation. The reason for this is that when you use Html Helpers to render your form fields, the CSS class is applied automagically by the Web Pages framework in the result of failed validation. All fields in the above code except the firstname field are Html helpers. If you want the input-validation-error style to be applied to normal HTML input elements, you need to state that explicitly with the Validation.ClassFor() method:

<input name="firstname" type="text" value="@Request["firstname"]" class="@Validation.ClassFor("firstname")" />

Unobtrusive Client Validation

So far, the example has shown server-side validation in action. And the new validation framework will always ensure that server-side validation takes place. However, as a convenience to your users, you may want to apply client-side validation, which runs in the browser and can give users instant feedback as they move through the form if they attempt to provide invalid values, or if fields are empty when they click the submit button. Since MVC 3, the ASP.NET MVC framework has included a mechnism called Unobtrusive Client Validation. This is a kind of bridge between server-side validators - applied using DataAnnotation attributes on model properties, and the popular jQuery Validate plugin. The same system has now been applied to the Web Pages framework, acting as a bridge between the server-side validators you apply through the Validation.Add or the Validation.RequireField(s) methods, and the jQuery Validate library. In order to get it to work with the form in the example, you need to do two things: first add references to jQuery, jQuery.Validate and jQuery.Validate.Unobtrusive:

        <title>Web Pages 2 Validation</title>
        <script src="~/Scripts/jquery-1.7.2.min.js" type="text/javascript"></script>
        <script src="~/Scripts/jquery.validate.min.js" type="text/javascript"></script>
        <script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
        <link href="~/Content/StyleSheet.css" rel="stylesheet" type="text/css" />

You can link to these files through Microsoft's AJAX CDN if you like: or get them in the download that accompanies this article. The second thing you need to do - but only where you are not using Html Helpers for form fields - is to explicitly tell jQuery to apply client-side validation through the Validation.For method:

<input name="firstname" type="text" value="@Request["firstname"]" class="@Validation.ClassFor("firstname")" @Validation.For("firstname") />

As with the Validation.ClassFor method, this is not needed when using Html Helpers. When you implement unobtrusive validation, additional attributes are generated by the framework based on the HTML5 data-* attribute. For example, here's the source for the Number Required field:

<input data-val="true" 
       data-val-range="Must be between 1 and 4" 
       data-val-required="Make sure you say how many you want" 
       value="" />

I've broken it over several lines so that it easier to see and to ensure it fits on your screen. The data-val attribute is set to true, and tells jQuery that this field should be validated on the client. The other data-val attributes are pretty self explanatory and ensure that the right type of validation is performed, and that the correct error messages are assoicated with the individual form field. It should be noted at this point that certain types of validation are not available on the client by default. These relate to data type validation: Validator.DateTime(), Validator.Decimal(), Validator.Float(), Validator.Integer(), Validator.Url(). However, these validators are checked on the server.

Validation has certainly taken a step forward in Web Pages 2, and the addition of the Validation helper and Validator class means that it is really easy to ensure that you only get acceptable data posted to your application. In addition, the simple integration with unobtrusive client validation is a nice win too - especially when used with Html helpers.

The sample illustrated above is available as a GitHub repo. It includes the Web Pages 2 assemblies in the bin folder so you can run it from WebMatrix 1 if you haven't upgraded yet.


Date Posted:
Last Updated:
Posted by:
Total Views to date: 123514


- Mike

Wow Web Pages just keep getting better and better! Nice tutorial.

- Kevin

Thanks for the post, I don't like the fact though that the validation logic is in the view. Is there a better approach for this?

In MVC currently you use model attributes which is great and seperates this from the view.

How do you see this being implemented in a more seperated way.

- Mike


There is no concept of "View" or "Model" in the Web Pages framework. It is designed as a lightweight Page-centric development model similar to classic ASP or PHP. If you need greater levels of separation, you should use MVC.

- wjx

when the page is in the root directory, It works fine; but when I put it in the Views directory, prompting System.Web.Helpers.Validation doesn’t contain ‘Add’ or ‘RequireField’ definition

- Mike


"Views" directory? Are you writing an MVC app? If so, you are better off using data annotations on your ViewModels for validation. This article covers validation in the Web Pages framework.

- Tunde Szabo

How to do validation when posting to another page? When I take out the action validation works (page posts back to itself) but when I try posting to another page, it does not work. I'm a complete newbie. Thanks in advance for any suggestions

- Mike


The validators are designed to work with forms that post to the same page.

- JT

There is a mistake near the top of the article where you 'specifying that a form field is mandatory'(your words) the Validation code is missing an 'a'.

- Law Abiding Citizen

Console.Writeln("BIG Thanks")

- Jaroslav

Hi Mike,
How can I do Validation on server side if I have two forms and I want to validate them individually?

- Kuberan

Hi, I keep getting this error message when I am using validation to insert into the database. It only happens when if (Validation.IsValid()

I am using web matrix and following the tutrails here:

Is this a program fault or is something wrong with my code:
Exception Details: System.OverflowException: Value was either too large or too small for an Int32.
Line 36:
Line 37: if (IsPost){
Line 38: if (Validation.IsValid()){var insertQuery = "INSERT INTO UserInfo (Name, Surname, IdNum, Address, ContNum, Course, Grade)" + "VALUES (@0, @1, @2, @3 ,@4, @5, @6)";
Line 39: db.Execute(insertQuery, Name, Surname, IDNumber, Address, ContactNumber, Course, grade);
Line 40: }

- Don

Great summary to get started with. Saved me hours of research. I will be passing your link on to my students.

- hardik patel

when I used this code in my project
Validation.Add doesn't work...
it through an error like System.Web.validation doesn't contain definition like Add.
Please help
Thank you

- Mike


You need to upgrade to Web Pages 2.

- Gautam

Hi Mike

Is this required for V3, non html helper input elements


- Mike


As far as I know, nothing changed between v2 and v3 of Web Pages in terms of the validation helpers.

- Gavin Medlin

Mike, can these be used when submitting the form via ajax?

- Mika

Thanks for this article, it is just great!

- Mike


You have to do a little more work to get the server-side error messages to appear.

- Dai Bando

Great, thanks.

Recent Comments

Thomas 05/03/2018 00:59
In response to I'm Not Writing A Book On Razor Pages
There's a typo on this page: = true)] should be [BindProperty(SupportsGet = true)]...

Rolf Herbert 04/03/2018 19:25
In response to I'm Not Writing A Book On Razor Pages
So is MS deprecating razor Web Pages..? Is it dead..? I wish they would stop killing things so its...

Borut 17/02/2018 12:59
In response to I'm Not Writing A Book On Razor Pages
Mike, is it possible that Web Pages and Razor Pages "live" together in one web application? I a I...

hrboyce 09/02/2018 04:44
In response to I'm Not Writing A Book On Razor Pages
Mike, First thanks for doing this but I have to ask, any chance you would consider converting one of...

aziz sallam 07/02/2018 10:18
In response to I'm Not Writing A Book On Razor Pages
u are a great man...

Satyabrata Mohapatra 31/01/2018 11:36
In response to I'm Not Writing A Book On Razor Pages
This is a great news!!!! Thanks...

tangdf 30/01/2018 07:25
In response to I'm Not Writing A Book On Razor Pages
=> { o.ConfigureFilter(new IgnoreAntiforgeryTokenAttribute()); }); The extension method does...

Obinna Okafor 30/01/2018 04:02
In response to I'm Not Writing A Book On Razor Pages
Thank you very much. I would like to see a project built from scratch using Razor Pages. And it show...

rachida Dukes 31/10/2017 13:52
In response to Customising Identity in Razor Pages
Thanks again for this wonderful tutorial. I followed all the steps in this section called: Adding...

Rachida 31/10/2017 12:06
In response to Customising Identity in Razor Pages
Thanks very much for this wonderful tutorial, it helped a lot....