Exercise 6: Adding Validation

Currently, the Create and Edit forms you have in place do not perform any kind of validation. If the user leaves a required field blank or type letters in the price field, the first error you will get will be from the database.

You can add validation to the application by adding Data Annotations to your model class. Data Annotations allow describing the rules you want applied to your model properties, and ASP.NET MVC will take care of enforcing and displaying appropriate message to users.

Additionally, you will add client-side (AJAX) validation that will check all fields in the browser before being submitted to the controller actions.

Task 1 – Adding Data Annotations

In this task, you will add Data Annotations to the Album Model that will make the Create and Edit page display validation messages when appropriate.

  1. Start Microsoft Visual Web Developer 2010 Express from Start | All Programs | Microsoft Visual Studio 2010 Express | Microsoft Visual Web Developer 2010 Express.
  2. In the File menu, choose Open Project. In the Open Project dialog, browse to Source\Ex06-AddingValidation\Begin, select MvcMusicStore.sln and click Open.

    Note:
    For a simple Model class, adding a Data Annotation is just handled by adding a using statement for System.ComponentModel.DataAnnotation, then placing a [Required] attribute on the appropriate properties.

    The following example would make the Name property a required field in the View.

    C#

    using System.ComponentModel.DataAnnotations;

    namespace SuperheroSample.Models

    {

    public class Superhero

    {

    [Required]

    public string Name { get; set; }

    public bool WearsCape { get; set; }

    }

    }

    Visual Basic

    Imports System.ComponentModel.DataAnnotations

    Public Class Superhero

    <Required>

    Public Property Name As String

    Public Property WearsCape As Boolean

    End Class

    This is a little more complex in cases like this application where the Entity Data Model is generated. If you added Data Annotations directly to the model classes, they would be overwritten if you update the model from the database.

    Instead, you can make use of metadata partial classes which will exist to hold the annotations and are associated with the model classes using the [MetadataType] attribute.

  3. Add a new metadata partial class. To do this, right-click the Models folder within the Solution Explorer, select Add and then New Item.
  4. In the Add New Item dialog, select the Class template, located under Visual [C#|Basic] -> Web template list. Change the name to Album.[cs|vb] and click Add.

    Figure 1

    Adding the Album class – C#

    Figure 36

    Adding the Album class - VB

  5. Replace Album.[cs|vb] content with the highlighted code, so that it looks like the following:

    (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex6 Album metadata partial class – CSharp)

    C#

    using System;
    FakePre-a54a1c30dcaa4fb09a1dbb2b7b1f1c70-abd6ed2325d14ae5853696fb109dce4aFakePre-cb58b7e67b2c419ab0c0347fbf34b0e1-6e0307fb2e2f443ca141f01327287c73FakePre-75d6e6f5c30a4d47ad0f5053609b8127-cde2f96123a447f4a61f83673799ad77using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Web.Mvc; namespace MvcMusicStore.Models { [MetadataType(typeof(AlbumMetaData))] public partial class Album { // Validation rules for the Album class [Bind(Exclude = "AlbumId")] public class AlbumMetaData { [ScaffoldColumn(false)] public object AlbumId { get; set; } [DisplayName("Genre")] public object GenreId { get; set; } [DisplayName("Artist")] public object ArtistId { get; set; } [Required(ErrorMessage = "An Album Title is required")] [DisplayFormat(ConvertEmptyStringToNull=false)] [StringLength(160)] public object Title { get; set; } [DisplayName("Album Art URL")] [StringLength(1024)] public object AlbumArtUrl { get; set; } [Required(ErrorMessage = "Price is required")] [Range(0.01, 100.00, ErrorMessage = "Price must be between 0.01 and 100.00")] public object Price { get; set; } } } }FakePre-83827e53aaea46899f5c38568a6d5137-00fe7c6dec894d2fb4a942de74ac0921FakePre-af8675ce73624551b3f0d1f993f783a8-b05a40590724406aa65260e59e9385a6FakePre-50a983f7118a420aa9fc42fc647dea34-fa207cc976df4369b7297e3445124968FakePre-587027316f894722a4ec82f0ad61c246-825f4cde5afa42fa96328095c3495b7cFakePre-e00d3f5586c7475d9b50317dd3738f26-4072f0fa4466469f9f78db1b024e202cFakePre-68bac379fe784dafa2440347adb7fe49-4ed868a932954a068e3b8ed45dc4046fFakePre-62cdb969ac8342fc83847943b9895f1f-5a5f2275e7f84ae5bc9b09d4bb86b29d

    (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex6 Album metadata partial class – VB)

    Visual Basic

    Imports System.ComponentModel Imports System.ComponentModel.DataAnnotations <MetadataType(GetType(Album.AlbumMetaData))> Partial Public Class Album 'Validation rules for the Album class <Bind(Exclude:="AlbumId")> Public Class AlbumMetaData <ScaffoldColumn(False)> Public Property AlbumId As Object <DisplayName("Genre")> Public Property GenreId As Object <DisplayName("Artist")> Public Property ArtistId As Object <Required(ErrorMessage:="An Album Title is required"), DisplayFormat(ConvertEmptyStringToNull:=False), StringLength(160)> Public Property Title As Object <DisplayName("Album Art URL"), StringLength(1024)> Public Property AlbumArtUrl As Object <Required(ErrorMessage:="Price is required"), Range(0.01, 100.0, ErrorMessage:="Price must be between 0.01 and 100.00")> Public Property Price As Object End Class End Class
    FakePre-52a7eaf471b7459ca255b31edc347e32-04e2196eb1634e38bbb0ef4e25d8806dFakePre-efb65a7a54164065bfe00f1198341839-feab7dc52fbf45998f0b8da2c3308c40FakePre-068f251e20e547878b631daadc92df14-9b0d16aace0c484b94f39f9fc32757e8FakePre-ea279311897c44dd9d8aba86d96b745d-86667b1690cd433f805739111a378181FakePre-0b630487770e4481956ce8e2f41a220c-8b8d49f658e84f8bbccdd96d1bb7d768FakePre-b90efcc3d8c4432980c0ed85349a9461-c5978fdd00a34edbb7b448ce6309e8a6
    

    Note:
    This Album partial class has a MetadataType attribute which points to the AlbumMetaData class for the Data Annotations. These are some of the Data Annotation attributes you are using to annotate the Album model:

    • Required – Indicates that the property is a required field

    • DisplayName – Defines the text to be used on form fields and validation messages

    • DisplayFormat – Specifies how data fields are displayed and formatted.

    • StringLength – Defines a maximum length for a string field

    • Range – Gives a maximum and minimum value for a numeric field

    • Bind – Lists fields to exclude or include when binding parameter or form values to model properties

    • ScaffoldColumn – Allows hiding fields from editor forms

    Note:
    The line [DisplayFormat(ConvertEmptyStringToNull=false)] indicates that empty strings from the model won’t be converted to null when the data field is updated in the data source. This setting will avoid an exception when the Entity Framework assigns null values to the model before Data Annotation validates the fields.

Task 2 – Running the Application

In this task, you will test that the Create and Edit pages validate fields, using the display names chosen in the last task.

  1. Press F5 to run the Application.
  2. The project starts in the Home page. Change the URL to /StoreManager/Create. Verify that the display names match the ones in the partial class (like Album Art URL instead of AlbumArtUrl)
  3. Click Save, without filling the form. Verify that you get the corresponding validation messages.

    Figure 37

    Validated fields in Create page

  4. You can verify that the same occurs with the Edit page. Change the URL to /StoreManager/Edit/388 and verify that the display names match the ones in the partial class (like Album Art URL instead of AlbumArtUrl). Empty the Title and Price fields and click Save. Verify that you get the corresponding validation messages.

    Figure 38

    Validated fields in Edit page

Task 3 – Adding Client-Side (AJAX) validation

In this task, you will add client-side (AJAX) validation to the forms to check all fields in the browser before being submitted to the controller actions.

  1. Close the browser if needed, to return to the Visual Studio window. Open /Views/Shared/EditorTemplates/Album.ascx
  2. Include the needed references to the libraries that will take care of the client-side validation:

    HTML(C#)

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcMusicStore.Models.Album>" %>
    FakePre-5b537b7da8614b03b063b599f95753ab-ab4bb2d6e46f4a4883e3542a4d26bc0e<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script> <script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script> <script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>

    HTML(Visual Basic)

    <%@ Page Title="" Language="VB" Inherits="System.Web.Mvc.ViewPage(Of MvcMusicStore.Album)" %>
    FakePre-0636d70c818b4f0a8f82d20da712ad5d-b13ac0a4ee8847e79866e5e4d37fb46f<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script> <script src="/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script> <script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script>

  3. Use the Html.EnableClientValidation helper method to turn on client-side validation. For both the Create and Edit view templates, add that call directly above the Html.BeginForm call. In order to do that, open /Views/StoreManager/Create.aspx and /Views/StoreManager/Edit.aspx and add the following:

    (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex6 Client-Side validation – CSharp)

    C#

    <% Html.EnableClientValidation(); %>
    FakePre-78be12a849d741c38c4e24bc6ecf0a83-7f6f204cf4c245b48dd8e1f4a83f218eFakePre-77ee34c6b3274ccab5ef73fdeba7401c-54a1952bcb46417ea0d17fde6221062aFakePre-9a01b7ed9ca149a0bb6a5329ba2830c5-53ef66e33abb4727aaf936eae88fcf05FakePre-b398a530a3fd4741adff31c01e194d30-c2d8db243aa848e6a2126c0409932f1f
    

    (Code Snippet – ASP.NET MVC 3 Helpers and Forms and Validation – Ex6 Client-Side validation – VB)

    Visual Basic

    <%Html.EnableClientValidation()%>
    FakePre-d61dff06552d40519e1b12ea8124f7f2-73f86707ee7443a7b1eed4dde5e12fe2FakePre-c0729391e74d460d90b6d27a312cfd37-2904eb38880f4bae866fddf35adb24e2FakePre-40cd0a237f0c4350a04b2965392f7e38-a99edf9e889f4fc79240d7400a70cb68
    

  4. Edit the Web.config in the project root to disable UnobtrusiveJavaScript. To do this, replace the appSettings entry with the following one:

    XML

    <configuration>
    FakePre-8c2ca48643ab4962a4e2e03e05e92ed4-ab33a77a27ca457bbba3af543ecae60bFakePre-85e51aa4c86741b799af3238dfaa1e85-219d49754a30463fb34a4f300ada4236FakePre-90bf9bac510e4b02a0b5ecc138dc1060-07ff742cbe204460a57c3200d416e631FakePre-db4769843d27450ebbf4c760471baa92-101ec0f7c5ef447286a02ffe636a538e

Task 4 – Running the Application

In this task, you will test that the Create and Edit pages validate fields in the browser before being submitted to the controller actions.

  1. Press F5 to run the Application.
  2. The project starts in the Home page. Change the URL to /StoreManager/Create. Enter a letter in the Price field and click anywhere else in the form, taking focus out of the text box. Verify that without submitting the form, the corresponding validation message appears.

    Figure 39

    Validated fields at client-side

  3. Delete the letter entered in the Price field and verify that the appropriate validation message appears without submitting the form.

    Figure 40

    Validated fields at client-side

Next Step

Summary