Share via


Exercise 3: Client and Server Side Validation in ASP.NET MVC 2

In this Exercise, you will learn how to add validation attributes to your model, and have them reflected in the UI, adding both client, and server side validation.

Out of the box, MVC provides the following set of validation rules which can be added to your model as attributes:

  • Required: defines if the property is required or not.
  • RegularExpression: matches the value of the property to the regular expression. Returns the value of the match.
  • Range: defines the range of valid values for the given property; (minValu, maxValue).
  • StringLength: defines the maximum length that the string property can have.

Adding simple Server-Side validation is extremely easy with the validation attributes support added in MVC 2, simply verifying if the ModelState is valid in your controller, and rendering the view if it is not should be enough.

if (!ModelState.IsValid)
{
return this.View();
}

If Not ModelState.IsValid Then
Return Me.View()
End If

Simple Client Side validation is also quite simple to add and uses the validation attributes added in the model, avoiding the needs of replicating the rules throught the application. Simply adding the following markup before the form definition should be enough:

<% Html.EnableClientValidation(); %>

<% Html.EnableClientValidation() %>

Note:
The framework also allows you to extend the validation functionality to provide custom rules which apply to your business model. To do this, you must inherit the ValidationAttribute class, overriding the IsValid method.

Task 0 – Exploring the Solution

In this task, you will explore the solution you obtained after completing exercise 2 to understand how client and server side validation is performed in a non-MVC2 application. This will help understanding the benefits provided by the MVC framework.

  1. Open Microsoft Visual Studio 2010. Click Start | All Programs | Microsoft Visual Studio 2010 | Microsoft Visual Studio 2010.
  2. Open the solution file Begin.sln located under \Ex3-Validation\begin\ (Choosing the folder that matches the language of your preference). Alternatively, you can continue working with the solution obtained after completing exercise 2.
  3. The Activity Create view performs validation of the data entered on several fields. These validations take place both on the client side (i.e. the browser) and on the server side (i.e. the view’s controller).
  4. Client side validation can be implemented in several ways; there also exists several frameworks to achieve the goal of validating data. One of those frameworks, very popular amongst MVC 1 users, is the jQuery Validation plugin. This plugin is included out-of-the-box in any version of the MVC project template for Visual Studio. To review these script files, expand the Scripts folder in the PlanMyNight project.

    Figure 25

    The jQuery Validation Plugin (C#)

    Figure 26

    The jQuery Validation Plugin (Visual Basic)

  5. Validation is executed on the client by the means of JavaScript code attached to the view. This code uses the jQuery Validation plugin to setup the rules to be applied on the fields included in the HTML form. In this case you can examine the required rules configured for the Name, PhoneNumber and Street input fields. Expand the Views\Activities folder in the PlanMyNight project and open the Create.aspx file to review the validation implementation.

    Figure 27

    Client Side Validation Rules using jQuery Validation Plugin

  6. Also, it is important to notice that because the validation occurs on the client, knowing the HTML id attribute is very important in order to properly setup the validation rules. Scroll up in the view markup and notice the call to the Html.BeginForm method for an example.

    Figure 28

    BeginForm method call (C#)

    Figure 29

    BeginForm method call (Visual Basic)

  7. On the other hand, server side validation is performed on the view’s controller. The ModelState object is used to send information about issues back to the view. When a model binder encounter input errors it automatically populates the ModelState collection, but for business rules validation an imperative approach is required. To review the view’s controller, expand the Controllers folder in the PlanMyNight and open the ActivitiesController.cs (C#) or ActivitiesController.vb (Visual Basic) class file.
  8. DataAnnotations provides a way to encapsulate validation ruleds in the model itself by providing a set of attributes that can be used as metadata to determine if the specified model is valid. In our example we use the TryValidateObject method of the Validator class to imperatively validate the model object. By using this approach we get a collection of errors that can be used to manually populate the ModelState collection to render the error messages on the view. To review this approach, scroll down to the Create method and examine the code below the commented line.

    Figure 30

    Server side imperative model validation (C#)

    Figure 31

    Server side imperative model validation (Visual Basic)

  9. This sample uses the RequiredAttribute to decorate properties that will be mapped to fields to get validated in the controller’s action. As you can notice, in the absence of a RequiredAttribute decorating the PhoneNumber property, the ActivityCreateModel validation attributes does not match the client side validation rules implemented using jQuery Validation plugin. This is a major disadvantage of this approach because you must maintain validation rules in sync manually. To verify this, expand the ViewModels folder in the PlanMyNight project and open the ActivityCreateModel.cs (C#) or ActivityCreateModel.vb (Visual Basic) class file.

    Figure 32

    ActivityCreateModel model validation attributes(C#)

    Figure 33

    ActivityCreateModel model validation attributes (Visual Basic)

Task 1 – Removing jQuery Client Side Validation

  1. In the ActivityCreateModel class you verified the lack of synchronization between client side and server side validation. You will make this difference more evident by removing the jQuery validation rules in the Create view. To do this, expand the Views\Activities folder and open the Create.aspx markup by double-clicking on the file.
  2. Luckily, the jQuery validation implementation is a little portion of code isolated at the bottom of the view markup. Since you want replace this portion of code with the MVC client validation, you can get rid of it. To do this, scroll down to the <script> section containing the jQuery validation and remove it.

    Figure 34

    Portion of Create.aspx file that should be removed.

  3. You will browse the Create page to verify that client side validation is not being performed. To do this, press CTRL + F5 to run the solution without debugging and when the browser is launched navigate to: https://localhost:50000/Activities/Create. When the page is fully loaded press CTRL + F5 to reload the page from the server in case it is stored in the browser’s cache.
  4. In the Create page fill the Name, Zip, Address and City fields with random data and press the Create button. No client validation will be performed and you will be redirected to the Details page when the new item is created in the database.

    Note:
    Remember that because validation is not fully enabled, you should enter valid data in order to avoid errors. For example, the Zip database field permits only five characters in its content.

    Figure 35

    Portion of Create.aspx file that should be removed.

  5. Now, clear all the fields in the page and press the Create. The server will perform validation and require the Name, Zip, Address and City fields to be entered.

    Figure 36

    Server side validation performed when client side validation is removed.

  6. Close the browser.

Task 2 – Removing Imperative Server Side Model Validation

  1. In a previous task you verified how the Activities controller performed imperative validation using the DataAnnotations Validation class and populating the ModelState object to send back errors to the view. This task is now performed automatically in ASP.NET MVC 2.0; consequently the code used to perform validation is no longer required. To do this, expand the Controllers folder and open the ActivitiesController.cs (C#) or ActivitiesController.vb (Visual Basic) class file by double-clicking on it. Scroll down to the Create method and remove the code below the commented line as in the following code.[AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(ActivityCreateModel model)
    {
    // Removed Validation code

    if (!ModelState.IsValid)
    {
    return this.Create();
    }
    ...
    }

    <AcceptVerbs(HttpVerbs.Post)>
    Public Function Create(ByVal model As ActivityCreateModel) As ActionResult
    ' Removed Validation code

    If (Not ModelState.IsValid) Then
    Return Me.Create()
    End If
    ...
    End Function

  2. As you can notice, the code to test the ModelState.IsValid property is still required since it contains the result of all validations.
  3. You will browse the Create page to verify that server side validation is being perfomed automatically. To do this, press CTRL + F5 to run the solution without debugging and when the browser is launched navigate to: https://localhost:50000/Activities/Create.
  4. Now, clear all the fields in the page and press the Create. The server will automatically perform validation and require the Name, Address, City and Zip fields to be entered.
  5. Close the browser.

Task 3 – Adding Model Validation Metadata

  1. MVC 2.0 validation engine uses validation metadata in the form of DataAnnotations attributes to describe the validation rules an object must conform. To add more strict validation rules you want to decorate the Phone property with the RequiredAttribute. To do this, open the ActivityCreateModel.cs (C#) or ActivityCreateModel.vb (Visual Basic) file located in the ViewModels folder and then replace the Phone property declaration with the bolded code below.[DisplayName("Phone:")]
    [Required(ErrorMessage = "Please enter the Activity Phone Number.")]
    public string Phone { get; set; }

    <DisplayName("Phone:")>
    <Required(ErrorMessage:="Please enter the Activity Phone Number.")>
    Public Property Phone() As String

  2. You will decorate the view model with more complex rules as well. In addition to the RequiredAttribute, decorate the Zip property with the StringLenghtAttribute. To do this, replace the Zip property declaration with the bolded code below.[DisplayName("Zip:")]
    [Required(ErrorMessage = "Please enter the Activity Zip.")]
    [StringLength(5, ErrorMessage = "Enter a valid Zip code for the Activity")]
    public string Zip { get; set; }

    <DisplayName("Zip:")>
    <Required(ErrorMessage:="Please enter the Activity Zip.")>
    <StringLength(5, ErrorMessage:="Enter a valid Zip code for the Activity")>
    Public Property Zip() As String

Task 4 – Enabling Client Side Validation

  1. ASP.NET MVC 2.0 includes support for client side validation based on jQuery Validation plugin out-of-the-box. Enabling client side validation simply involves calling Html.EnableClientValidation () before you call Html.BeginForm (). Under the hood, this sets a flag in the ViewContext which lets the BeginForm method know that client validation is enabled. To do this, expand the Views\Activities folder in the PlanMyNight project and open the Create.aspx file by double-clicking on it. Then, scroll down to the Html.BeginForm() method call and paste the following bolded code in the line above.<%Html.EnableClientValidation();%>
    <% using (Html.BeginForm())
    {%>

    <% Html.EnableClientValidation()%>
    <% Using (Html.BeginForm())%>

  2. Also, you confirmed that jQuery validation implementation require to specify the id attribute of the resulting HTML form. If you set an id for the form, the MVC runtime will know which ID to use when hooking up client validation. If you don’t, the form will render one for you. Update the call to the Html.BeginForm () method to not pass parameters. To do this, replace the Html.BeginForm () method call using four parameters by the following bolded code.<% using (Html.BeginForm())
    {%>

    <% Using (Html.BeginForm())%>

  3. Since out-of-the-box validation is based on JQuery you want to confirm you include the required script files. Also, the MVC implementation of client validation includes the MicrosoftMvcJQueryValidation.js script file which adapts the jQuery Validation plugin to an MVC application. To verify this, expand the Views\Shared folder in the PlanMyNight project and open the Site.Master file. You will notice the references to the three required script files.

    Figure 37

    Master page referencing the script files required for client validation.

Exercise 3: Verification

  1. Press CTRL+F5 to run the solution without debugging.
  2. You will open the Create Activity view to review the results of the work done. To do this, edit your browser’s address bar to navigate to https://localhost:50000/Activities/Create.
  3. First, you will verify that added model validation metadata is replicated on the client side validation rules. To do this, clear all the fields in the view and click on the Create button. Validation will occur on the client side without a roundtrip to the server.

    Figure 38

    Client side validation in sync with model validation metadata.

  4. Now, you will verify specifically one of the new included model validation metadata attributes. In the second task you decorated the Zip property with a StringLength attribute to ensure the zip value has a maximum length of 5 characters.
  5. You will verify the string length rule by entering a value on each of the required fields: Name, Address and Phone. Additionally, enter a long string value in the Zip field with more than 5 characters, for example enter “123456” and then click on the Create button. A client validation message should appear.

    Figure 39

    Client side validation in sync with model validation metadata using String Length rule.

  6. Close the browser.