ASP.NET MVC Data Annotation – Server Side Validation of Controls – Textbox, Dropdownlist, Checkbox, Radiobutton

ASP.NET MVC Data Annotation – Server Side Validation of Controls – Textbox, Dropdownlist, Checkbox, Radiobutton

Whenever a form is submitted you should ensure to do the Server Side Validation of every control so that the received data is correct and valid.

Some developers provide only client side validation and leave the server side validation in their projects. This is a wrong practice as users can disable JavaScript on their browser and bypass the Client Side Validation. Therefore always make sure to do Server Side Validation in your project.

Server Side Validation Method in ASP.NET MVC

In ASP.NET MVC application we can do the Server Side Validation on the Model using Data Annotations.

Data Annotations is a namespace, providing attribute classes, which are used to define metadata for controls. In MVC we decorate model properties with these attribute classes to provide metadata.

This metadata describes a set of rules that are used to validate model property.

MVC Provides large number of Data Annotations class. Some important ones are:

Name Definition
[Required] Data field is required.
[RegularExpression(string pattern)] Data field value must match the specified regular expression pattern.
[Range(int minimum, int maximum)] Data field value must lie within the minimum and maximum range.
[DataType(DataType dataType)] Data field value must match with the data type specified.
[EmailAddress] The value must be an email address.
[Phone] The value must be phone number.

In case, if you want to do the custom validation of a control, then you can create you our Custom Validation Attribute Class. In this class you write the validation code. I will explain how to create Custom Attribute Class later in this tutorial.

Server Side Validation of a Form using Data Annotations

To help you understand Data Annotations I will create a Job Application form that will have number of fields. Through this form a user can apply for a job.

The form will look like:

job application form

On this form there will be a button which on clicking will submit the Job Application form. I will ensure the server side validations takes place for every form field.

First thing is to create a model for this form. In this model I will create the form fields and set the data annotations attributes to them.

Right click on the Model folder and create a new class, name this class JobApplication.cs.

Add the following fields to it:

You will be required to include the namespace using System.ComponentModel.DataAnnotations; at the top of this class.

1. Name: A required field, just provide Required attribute to it.

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

2. Experience: Only numbers and decimals, and should be between 3 and 15. Valid ones are – 3 , 5.7, 13, etc.

Provide Range attribute to it:

[Range(3, 15, ErrorMessage = "Experience must be from 3 to 15 years")]
public int experience { get; set; }

3. BirthDate: Must be a data and between 01-25-1970 & 01-25-2000. For this field I provide 2 attributes –

a. DataType for specifying it to be of date time.

[DataType(DataType.Date)]

b. A custom attribute through which I do the manual server side validation.

[ValidBirthDate(ErrorMessage = "DOB Should be between 01-25-1970 & 01-25-2000")]

It will look like:

[Display(Name = "Date of Birth")]
[DataType(DataType.Date)]
[ValidBirthDate(ErrorMessage = "DOB Should be between 01-25-1970 & 01-25-2000")]
public DateTime birthDate { get; set; }
The Display Attributes set the display field as “Date of Birth”.

Next I have to create this ValidBirthDate attribute class. I choose to create this class in a Class folder. So first create the Class folder in your project.

Then right click on this folder and add a new class to it. Name this class CustomValidation.cs.

In this class create a new sealed class ValidBirthDate and derive it from ValidationAttribute class.

We have to override the IsValid() method. Inside this IsValid() method I write my validation code, so that the date should always be between “01-25-1970” and “01-25-2000”.

In this way custom validation of BirthDate field is done.

The code of ValidBirthDate class is given below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;

namespace demo.MVC.Class
{
    public class CustomValidation
    {
    }
    public sealed class ValidBirthDate : ValidationAttribute
    {
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            DateTime _birthJoin = Convert.ToDateTime(value);
            DateTime minDate = Convert.ToDateTime("01-25-1970");
            DateTime maxDate = Convert.ToDateTime("01-25-2000");

            if (_birthJoin > minDate && _birthJoin < maxDate)
                return ValidationResult.Success;
            else
                return new ValidationResult(ErrorMessage);
        }
    }
} 

4. Email: This field should be required and must match with the email regular expression (so that invalid email addresses are not submitted). Its code will be:

[Required]             
[RegularExpression(@"^[A-Za-z0-9._%+-][email protected][A-Za-z0-9.-]+\.[A-Za-z]{2,4}$", ErrorMessage = "Invalid email")]
public string email { get; set; }

5. Sex: I will use a dropdownlist for taking value of user’s sex. The dropdownlist control will have 3 options –Select, Male & Female. A person should select either male or female.

Note: The values of Male and Female options are M and F.

The code for this is:

[SexValidation(ErrorMessage = "Select your sex")]
public string sex { get; set; }

SexValidation is a custom validation attribute and I will have to create a custom validation class for it.

So just as we did for the custom validation of date of birth, create SexValidation class inside the CustomValidation.cs class.

The code for SexValidation class is:

public class SexValidation : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (Convert.ToString(value) == "M" || Convert.ToString(value) == "F")
            return ValidationResult.Success;
        else
            return new ValidationResult(ErrorMessage);
    }
}
In the above code you will note that I checked dropdownlist’s selected option value (“M” of “F”). If selected value is either from one of them, then I returned ValidationResult.Success else “Select your sex” text is returned (through new ValidationResult(ErrorMessage)).

6. ExpectedMonthlySalary: It should be up to 2 places of decimal examples 3500.00, 4290.79, etc.
I provide it a RegularExpression attribute with a regular expression to match the valid salary format:

[RegularExpression(@"^(0(?!\.00)|[1-9]\d{0,6})\.\d{2}$", ErrorMessage = "Invalid salary 3500.50")]
public decimal expectedMonthlySalary { get; set; } 

7. Skills: User will have to select his skills from (C#, ASP, jQuery, etc) and he should select at least 3 skills from it. I will have to create a custom validation class to do this check. Moreover these skills will be shown through checkboxes.

First create a property skills with custom validation attribute SkillValidation.

[SkillValidation(ErrorMessage = "Select at least 3 skills")]
public List<CheckBox> skills { get; set; }

As you can see the skills property is of type List. Checkbox will be another model class that will contain the IsChecked property. In the View I will create the checkboxes form IsChecked propery.

So create a new Checkbox.cs class in the model folder and add the below code:

public class CheckBox
{
    public bool IsChecked { get; set; }
}

Next create the SkillValidation class in the CustomValidation.cs class.

public class SkillValidation : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        List<CheckBox> instance = value as List<CheckBox>;
        int count = instance == null ? 0 : (from p in instance
                                                where p.IsChecked == true
                                                select p).Count();
        if (count >= 3)
            return ValidationResult.Success;
        else
            return new ValidationResult(ErrorMessage);
    }
}
I used Linq to check whether the user has checked at least 3 skills or not.

8. UsWorkPermit: User must select whether he/she has the USA work permit. I will show this through 2 Radio buttons.

In the JobApplication model create a string property for it and provide the Required attribute.

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

9. PreviousJobDescription: In this user will have to provide details about his previous job.

Make this property string type and provide it Required attribute.

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

10. Terms: This is the last field where user has to select the terms checkbox. I make this property as Boolean and provide it with a custom validation attribute RequiredTerms.

[RequiredTerms(ErrorMessage ="Must accept our terms")]
public Boolean terms { get; set; }

Add the RequiredTerms class in the CustomValidation.cs.

public sealed class RequiredTerms : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if (Convert.ToBoolean(value) == false)
            return new ValidationResult(ErrorMessage);
        else
            return ValidationResult.Success;
    }
}

Creating “Job Application” Controller

Add a new controller and name it JobApplicationController.

The controller already has the Index ActionResult of type GET. Create another Index ActionResult of type POST.

[HttpPost]
[ValidateInput(false)]
public ActionResult Index(Models.JobApplication jobApplication)
{
    if (ModelState.IsValid)
        ViewBag.Result = "Form Submitted Successfully.";
    else
        ViewBag.Result = "Invalid Entries, Kindly Recheck.";
    return View();
} 

When the submit button is clicked then the control moves to this HttpPost Index ActionResult. Here I check if all submitted values are in correct format.

If ModelState.IsValid is true then submitted values are in correct format. The ViewBag stores a value that I will show in the view.

Creating the “Index” View

In the view I will also place a text editor for Previous Job Description. I will use CKEditor which you can download from here.

Add the CKEditor folder in your project and give its ckeditor.js file’s reference on top of the Index view like this:

<script src="~/Content/Component/ckeditor/ckeditor.js" type="text/javascript" language="javascript"></script>

Next add the reference to the Model:

@model demo.MVC.Models.JobApplication

Followed by CSS to design the form:

<style>
    #viewContent .jobApplicationDiv label {
        display: block;
        margin: 0;
        text-transform: capitalize;
    }

    #viewContent .jobApplicationDiv table tr > td > span {
        display: block;
        color: burlywood;
    }

    #viewContent table {
        width: 100%;
    }

        #viewContent table tr {
            height: 80px;
            background: darkcyan;
        }

            #viewContent table tr td {
                width: 50%;
                padding-left: 5px;
            }

    #viewContent .studentDiv {
        padding-top: 25px;
    }

        #viewContent .studentDiv table thead {
            background-color: #0f40e0;
        }

        #viewContent .studentDiv table tbody {
            background-color: #ff6a00;
        }
</style>

Next create the controls from the model properties by putting the below code in your view:

<h3>@ViewBag.Result</h3>
<div id="viewContent">
    <div class="jobApplicationDiv">
        @using (Html.BeginForm())
            {
            <table>
                <tr>
                    <td>
                        @Html.LabelFor(model => model.name)
                        @Html.EditorFor(model => model.name)
                        @Html.ValidationMessageFor(model => model.name)
                    </td>
                    <td>
                        @Html.LabelFor(model => model.experience)
                        @Html.EditorFor(model => model.experience)
                        @Html.ValidationMessageFor(model => model.experience)
                    </td>
                </tr>
                <tr>
                    <td>
                        @Html.LabelFor(model => model.birthDate)
                        @Html.EditorFor(model => model.birthDate)
                        @Html.ValidationMessageFor(model => model.birthDate)
                    </td>
                    <td>
                        @Html.LabelFor(model => model.email)
                        @Html.EditorFor(model => model.email)
                        @Html.ValidationMessageFor(model => model.email)
                    </td>
                </tr>
                <tr>
                    <td>
                        @Html.LabelFor(model => model.sex)
                        @Html.DropDownListFor(model => model.sex, new List<SelectListItem> { new SelectListItem { Text = "Select", Value = "Select" }, new SelectListItem { Text = "Male", Value = "M" }, new SelectListItem { Text = "Female", Value = "F" } })
                        @Html.ValidationMessageFor(model => model.sex)
                    </td>
                    <td>
                        @Html.LabelFor(model => model.expectedMonthlySalary)
                        @Html.EditorFor(model => model.expectedMonthlySalary)
                        @Html.ValidationMessageFor(model => model.expectedMonthlySalary)
                    </td>
                </tr>
                <tr>
                    <td>
                        @Html.LabelFor(model => model.skills)
                        @Html.CheckBoxFor(m => m.skills[0].IsChecked, new { id = "csharpSkill" }) C#
                        @Html.CheckBoxFor(m => m.skills[1].IsChecked, new { id = "aspSkill" }) ASP.NET
                        @Html.CheckBoxFor(m => m.skills[2].IsChecked, new { id = "jquerySkill" }) jQuery
                        @Html.CheckBoxFor(m => m.skills[3].IsChecked, new { id = "mvcSkill" }) ASP.NET MVC
                        @Html.CheckBoxFor(m => m.skills[4].IsChecked, new { id = "razorSkill" }) Razor
                        @Html.CheckBoxFor(m => m.skills[5].IsChecked, new { id = "htmlSkill" }) HTML
                        @Html.ValidationMessageFor(model => model.skills)
                    </td>
                    <td>
                        @Html.LabelFor(model => model.usWorkPermit)
                        @Html.RadioButtonFor(m => m.usWorkPermit, "True") Yes I have
                        @Html.RadioButtonFor(m => m.usWorkPermit, "False") No I don't
                        @Html.ValidationMessageFor(model => model.usWorkPermit)
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        @Html.LabelFor(model => model.previousJobDescription)
                        @Html.TextAreaFor(model => model.previousJobDescription)
                        @Html.ValidationMessageFor(model => model.previousJobDescription)
                        <script type="text/javascript" language="javascript">
                            CKEDITOR.replace(@Html.IdFor(model => model.previousJobDescription));
                            CKEDITOR.config.toolbar = [
                               ['Styles', 'Format', 'Font', 'FontSize'],
                               '/',
                               ['Bold', 'Italic', 'Underline', 'StrikeThrough', '-', 'Undo', 'Redo', '-', 'Cut', 'Copy', 'Paste', 'Find', 'Replace', '-', 'Outdent', 'Indent', '-', 'Print'],
                               '/',
                               ['NumberedList', 'BulletedList', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
                               ['Image', 'Table', '-', 'Link', 'Flash', 'Smiley', 'TextColor', 'BGColor', 'Source']
                            ];
                        </script>
                    </td>
                </tr>
                <tr>
                    <td colspan="2">
                        Accept our Terms and conditions
                        @Html.CheckBoxFor(model => model.terms)
                        @Html.ValidationMessageFor(model => model.terms)
                    </td>

                </tr>
                <tr><td colspan="2"><button id="submitButton" type="submit">Submit</button></td></tr>
            </table>
        }
    </div>
</div>

Explanation
The ViewBag.Result will show the message returns from the controller. In the view, I am showing all the controls in HTML Table format. I created them like this:

1. Name: Created with with EditorFor method @Html.EditorFor(model => model.name). The EditorFor method will create a textbox for the name property of the model in the view.

I have also used LabelFor for showing name of the property and ValidationFor for showing the validation message arising when filling bad entries.

2. Experience: Created with @Html.EditorFor(model => model.experience). In the model I defined this property as Int so user will not be able to put anything accept numbers.

3. BirthDate: Created with @Html.EditorFor(model => model.birthDate). It will be a text box accepting only date values.

4. Email: Created with @Html.EditorFor(model => model.email), a text box accepting only emails.

5. Sex: Created with DropDownListFor method @Html.DropDownListFor(model => model.sex, new List { new SelectListItem { Text = “Select”, Value = “Select” }, new SelectListItem { Text = “Male”, Value = “M” }, new SelectListItem { Text = “Female”, Value = “F” } }) .

As you remember, I validate it with custom validation class SexValidation

6. ExpectedSalary: Will be textbox created with @Html.EditorFor(model => model.expectedMonthlySalary).

7. Skills: Will be 6 checkbox which will be created using CheckBoxFor method like:

@Html.CheckBoxFor(m => m.skills[0].IsChecked, new { id = "csharpSkill" }) C#
@Html.CheckBoxFor(m => m.skills[1].IsChecked, new { id = "aspSkill" }) ASP.NET
@Html.CheckBoxFor(m => m.skills[2].IsChecked, new { id = "jquerySkill" }) jQuery
@Html.CheckBoxFor(m => m.skills[3].IsChecked, new { id = "mvcSkill" }) ASP.NET MVC
@Html.CheckBoxFor(m => m.skills[4].IsChecked, new { id = "razorSkill" }) Razor
@Html.CheckBoxFor(m => m.skills[5].IsChecked, new { id = "htmlSkill" }) HTML

8. UsWorkPermit: I will show radiobuttons for this so I used RadiButtonFor method:

@Html.RadioButtonFor(m => m.usWorkPermit, "True") Yes I have
@Html.RadioButtonFor(m => m.usWorkPermit, "False") No I don't

9. PreviousJobDescription: I will show it with CKEditor. So first I create a text area for this property:

@Html.TextAreaFor(model => model.previousJobDescription)

Then use the CKEditor script to convert it to a text editor:

<script type="text/javascript" language="javascript">
    CKEDITOR.replace(@Html.IdFor(model => model.previousJobDescription));
    CKEDITOR.config.toolbar = [
        ['Styles', 'Format', 'Font', 'FontSize'],
        '/',
        ['Bold', 'Italic', 'Underline', 'StrikeThrough', '-', 'Undo', 'Redo', '-', 'Cut', 'Copy', 'Paste', 'Find', 'Replace', '-', 'Outdent', 'Indent', '-', 'Print'],
        '/',
        ['NumberedList', 'BulletedList', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
        ['Image', 'Table', '-', 'Link', 'Flash', 'Smiley', 'TextColor', 'BGColor', 'Source']
    ];
</script>

10. Terms: will be a checkbox created with CheckBoxFor method:

@Html.CheckBoxFor(model => model.terms)

Testing the Server Side Validations

Having done with the coding part let us test the server side validations. Run the page in the browser, and click the submit button. You will get validation message from ViewBag.Result telling – “Invalid Entries, Kindly Recheck.”. The validation errors will also be shown under every control.

server side validation messages

Now fill the values on each control and submit the form. This time the form submits and you receive the message “Form Submitted Successfully”.

form submitted successfully

DEMO DOWNLOAD

Next you should learn how to do Client Side Validation in ASP.NET MVC. I will update this Job Application form and enable Client Validations on it with jQuery.

Share this article -

yogihosting

ABOUT THE AUTHOR

This article has been written by the Technical Staff of YogiHosting. Check out other articles on “WordPress, SEO, jQuery, HTML” and more.