Showing posts with label Custom Annotations. Show all posts
Showing posts with label Custom Annotations. Show all posts

Custom DataAnnotation attribute to validate Password in MVC3 Razor


  1. Data Annotation attributes are used to validate the user inputs while posting the form.
  2. All the Data Annotation attributes like Required, Range are derived from ValidationAttribute class which is a abstract class.
  3. The ValidationAttribute base class lives in System.ComponentModel.DataAnnotations namespace.
  4. We can create our own Custom Annotation attribute which will have validation defined by us. 
  5. We have to inherit ValidationAttribute base class to create Custom Annotation attribute.
  6. In this article we will create Custom annotation attribute to validate Password.

ViewModel :


First we need to have a ViewModel in place where we will define our properties to render on UI. The ViewModel class looks like below :


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
  
namespace CustomValidation.Models
{
    public class Register
    {
        public string FirstName { get; set; }
  
        public string LastName { get; set; }
  
        public int Age { get; set; }
  
        public string Email { get; set; }
  
        public string Password { get; set; }
    }
}

The above is our ViewModel. We have defined properties we want on the form. We will pass this ViewModel to view. Currently we have not applied any DataAnnotation attribute to properties.

View :



@model CustomValidation.Models.Register

@{
    ViewBag.Title = "Register";
    Layout = null;
}



<h2 align="center">Register</h2>
@using (Html.BeginForm("Welcome","Register",new {@id = "formClass"}))
{
    <fieldset style="width:400px;">
    <legend>Registration Form</legend>
    @Html.EditorForModel("Register")
    <br /><br />
    <input type="submit" value="Submit" />
    </fieldset>
}

We have strongly binded the View with our ViewModel. We have created a form and used EditorForModel  HTML Helper to create controls for properties in the ViewModel. We have also created a Submit button to submit the form.

Custom DataAnnotation class for Password :



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

namespace CustomValidation.CustomValidator
{
    public class CustomPasswordValidator:ValidationAttribute
    {
        //Defined two private read only variables, to hold minimum and maximum length of password supplied using attribute definition.
        private readonly int minLen;
        private readonly int maxLen;

        //The constructor accepts two parameters. These parameters have to be supplied while applying this attribute.
        //We are also passing a default message to base class. This is default message.
        public CustomPasswordValidator(int minLength, int maxLength)
            : base("{0} length should be between " + minLength + " and " + maxLength + "")
        {
            minLen = minLength;
            maxLen = maxLength;

        }


        //We have override the IsValid method which accepts value and ValidationContext object.
        //value is the input provided by user from Form. The value which is posted from form.
        //Validation context object has details about the property on which this attribute is used.
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {

            //Validating user input.
            //The value is null, if the user leaves age field balnk on form.
            //We are returing error message in the else part of this if.
            //This check works like Required attribute.
            if (value != null)
            {
                //Converting the value to integer from object type.
                string userValue = value.ToString();

                //Comparing the length of password entered with the minimum limit.
                if (userValue.Length < minLen)
                {
                    //If the length of password is less than the applied length, validation message is thrown.
                    return new ValidationResult("Password cannot be less than 6 letters.");
                }
                //Comparing the length of password entered with the maximum limit.
                else if (userValue.Length > maxLen)
                {
                    //If the length of password is greater than the applied length, validation message is thrown.
                    return new ValidationResult("Password cannot be greater than 12 letters");
                }
                else
                {
                    //If the supplied password passes all the validations success result is returned.
                    return ValidationResult.Success;
                }
            }
            else
            {
                //If the user does not provide his password. The mandatory error message is shown.
                return new ValidationResult("Password is manadatory Field.");
            }
            
        }
    }
}

The above class validates the user's password. The user's password is validated against defined maximum and minimum limits i.e. number of words allowed. We have also validated the presence of user's input. If user leaves the age field blank, error message is thrown. 


How to apply :

[DataType(DataType.Password)]
[CustomPasswordValidator(6,12)]
public string Password { get; set; }


UI :




In the above case, we tried to enter password less than 6 letters. The validation attribute throws an error saying password cannot be less than 6 letters.


In the above case, we tried to enter password greater than 12 letters. The validation attribute throws an error saying password cannot be greater than 12 letters.



We have also validated user input for null or blank value. If user tries to leave password field blank, then validation attribute throws an error.

Thus we can include more validations in the same class. We can also verify whether a password contains special characters or not and many more validations.

Custom DataAnnotation attribute to validate Email Address


  1. Data Annotation attributes are used to validate the user inputs while posting the form.
  2. All the Data Annotation attributes like Required, Range are derived from ValidationAttribute class which is a abstract class.
  3. The ValidationAttribute base class lives in System.ComponentModel.DataAnnotations namespace.
  4. We can create our own Custom Annotation attribute which will have validation defined by us. 
  5. We have to inherit ValidationAttribute base class to create Custom Annotation attribute.
  6. In this article we will create Custom annotation attribute to validate Email-Id.


ViewModel :

First we need to have a ViewModel in place where we will define our properties to render on UI. The ViewModel class looks like below :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
  
namespace CustomValidation.Models
{
    public class Register
    {
        public string FirstName { get; set; }
  
        public string LastName { get; set; }
  
        public int Age { get; set; }
  
        public string Email { get; set; }
  
        public string Password { get; set; }
    }
}

The above is our ViewModel. We have defined properties we want on the form. We will pass this ViewModel to view. Currently we have not applied any DataAnnotation attribute to properties.

View :



@model CustomValidation.Models.Register

@{
    ViewBag.Title = "Register";
    Layout = null;
}



<h2 align="center">Register</h2>
@using (Html.BeginForm("Welcome","Register",new {@id = "formClass"}))
{
    <fieldset style="width:400px;">
    <legend>Registration Form</legend>
    @Html.EditorForModel("Register")
    <br /><br />
    <input type="submit" value="Submit" />
    </fieldset>
}

We have strongly binded the View with our ViewModel. We have created a form and used EditorForModel  HTML Helper to create controls for properties in the ViewModel. We have also created a Submit button to submit the form.

Custom Email Validator Class :



using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
//Namespace to use ValidationAttribute class
using System.ComponentModel.DataAnnotations;
//Name space to use regulsr expression.
using System.Text.RegularExpressions;

namespace CustomValidation.CustomValidator
{
    public class CustomEmailValidator : ValidationAttribute
    {
        //We have override the IsValid method which accepts value and ValidationContext object.
        //value is the input provided by user from Form. The value which is posted from form.
        //Validation context object has details about the property on which this attribute is used.
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            //Validating user input.
            //The value is null, if the user leaves age field balnk on form.
            //We are returing error message in the else part of this if.
            //This check works like Required attribute.
            if (value != null)
            {
                //Converting the value to integer from object type.
                string email = value.ToString();

                //Validating email id entered by the user against regular expression.
                if(Regex.IsMatch(email,@"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}"))
                {
                    //If email address is valid according to regular expression, suceess validation result is returned.
                   return  ValidationResult.Success;
                }
                else
                {
                    //If the email address is not accoring to the regular expression, error message is returned.
                    return new ValidationResult("Email Format is incorrect.");
                }
            }
            else
            {
                //If the user does not provide his age. The mandatory error message is shown.
                return new ValidationResult(""+ validationContext.DisplayName +" field is manadatory");
            }
        }
    }
}

The above class validates the user's email. The user's email is validated against regular expression. The error message is return if email does not matches the expression. We have also applied validation to check if email supplied by user is null or not.

How to apply :



[CustomEmailValidator]
public string Email { get; set; }

We applied our custom class to the email property in the ViewModel. CustomEmailValidator is the name of our class.

UI :




In the above screenshot I have entered email address which is not a proper address and also against our regular expression. The validation attribute class thrown error.


In the above screenshot, I have not supplied email address. The validation attribute class has thrown validation message.

We can customize the above class to have more validations and even customize the regular expression to support different formats of email addresses.


Custom DataAnnotation attribute to validate Age or integer inputs


  1. Data Annotation attributes are used to validate the user inputs while posting the form.
  2. All the Data Annotation attributes like Required, Range are derived from ValidationAttribute class which is a abstract class.
  3. The ValidationAttribute base class lives in System.ComponentModel.DataAnnotations namespace.
  4. We can create our own Custom Annotation attribute which will have validation defined by us. 
  5. We have to inherit ValidationAttribute base class to create Custom Annotation attribute.
  6. In this article we will create Custom annotation attribute to validate integer inputs with their limits like AGE.


ViewModel :

First we need to have a ViewModel in place where we will define our properties to render on UI. The ViewModel class looks like below :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
 
namespace CustomValidation.Models
{
    public class Register
    {
        public string FirstName { get; set; }
 
        public string LastName { get; set; }
 
        public int Age { get; set; }
 
        public string Email { get; set; }
 
        public string Password { get; set; }
    }
}


The above is our ViewModel. We have defined properties we want on the form. We will pass this ViewModel to view. Currently we have not applied any DataAnnotation attribute to properties.



View :


Our View looks like below :

@model CustomValidation.Models.Register

@{
    ViewBag.Title = "Register";
    Layout = null;
}



<h2 align="center">Register</h2>
@using (Html.BeginForm("Welcome","Register",new {@id = "formClass"}))
{
    <fieldset style="width:400px;">
    <legend>Registration Form</legend>
    @Html.EditorForModel("Register")
    <br /><br />
    <input type="submit" value="Submit" />
    </fieldset>
}

We have strongly binded the View with our ViewModel. We have created a form and used EditorForModel  HTML Helper to create controls for properties in the ViewModel. We have also created a Submit button to submit the form.


Custom Age DataAnnotation class :




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

namespace CustomValidation.CustomValidator
{
    public class CustomAgeValidator : ValidationAttribute
    {
        //Defined two private read only variables, to hold minimum and maximum age supplied using attribute definition.
        private readonly int lowerLimit;
        private readonly int higherLimit;

        //The constructor accepts two parameters. These parameters have to be supplied while applying this attribute.
        //We are also passing a default message to base class. This is default message. 
        public CustomAgeValidator(int minAge, int maxAge)
            : base("{0} should be between " + minAge + " and " + maxAge + "")
        {
            lowerLimit = minAge;
            higherLimit = maxAge;
        }

        //We have override the IsValid method which accepts value and ValidationContext object.
        //value is the input provided by user from Form. The value which is posted from form.
        //Validation context object has details about the property on which this attribute is used.
        protected override ValidationResult  IsValid(object value, ValidationContext validationContext)
        {
          //Converting the value to integer from object type.
            int userValue = Convert.ToInt32(value);
//Validating user input.
            //The value is null, if the user leaves age field balnk on form.
            //We are returing error message in the else part of this if.
            //This check works like Required attribute.
           if (value != null)
            {
                //Here we are validating whether the user age is according to the accepted limits.
                if (userValue >= lowerLimit && userValue <= higherLimit)
                {
                    //We return success validation result, if the age is in limit.
                    return ValidationResult.Success;
                }
                else
                {
                    //If the user's age is not within the accepted limits error message is returned.
                    //As we have passed the default message above. We have passed a placeholder with it.
                    //The display name is passed as parameter. And error message is displayed.
                    var errorMessage = FormatErrorMessage(validationContext.DisplayName);
                    return new ValidationResult(errorMessage);
                }
            }
            else
            {
                //If the user does not provide his age. The mandatory error message is shown.
                return new ValidationResult("Age is manadatory Field");
            }
             
        }

    }
}

The above class validates the user age. The user's age is validated against defined maximum and minimum limits. We have also validated the presence of user's input. If user leaves the age field blank, error message is thrown.

How to apply :



[CustomAgeValidator(20, 40)]
public int Age { get; set; }

The CustomAgeValidator is the name of class. We are passing minimum and maximum age limit as 20 and 40.

UI : 



The validator throws error when user supplied age not between 20 and 40.



The validator also throws error when user leaves the age field blank. This works similar to the Required DataAnnotation attribute. 
In the same manner we can apply as many as validation we want by creating Custom Annotation attributes.



Custom Data Annotation attribute to validate string inputs like Name.



  1. Data Annotation attributes are used to validate the user inputs while posting the form.
  2. All the Data Annotation attributes like Required, Range are derived from ValidationAttribute class which is a abstract class.
  3. The ValidationAttribute base class lives in System.ComponentModel.DataAnnotations namespace.
  4. We can create our own Custom Annotation attribute which will have validation defined by us. 
  5. We have to inherit ValidationAttribute base class to create Custom Annotation attribute.
  6. In this article we will create Custom annotation attribute to validate string inputs like name.



ViewModel : 


First we need to have a ViewModel in place where we will define our properties to render on UI. The ViewModel class looks like below.



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

namespace CustomValidation.Models
{
    public class Register
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public int Age { get; set; }

        public string Email { get; set; }

        public string Password { get; set; }
    }
}

We have created a Register class with some properies. This properties are used to bind the form and render the controls.



View :




@model CustomValidation.Models.Register

@{
    ViewBag.Title = "Register";
    Layout = null;
}



<h2 align="center">Register</h2>
@using (Html.BeginForm("Welcome","Register",new {@id = "formClass"}))
{
    <fieldset style="width:400px;">
    <legend>Registration Form</legend>
    @Html.EditorForModel("Register")
    <br /><br />
    <input type="submit" value="Submit" />
    </fieldset>
}

We have used EditorForModel helper to render the form.



Custom Name attribute class :


We have created a separate folder to include class files. The class file for Custom Annotation Attribute looks like below :




using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
//We have include the below namespace to use DataAnnotations
using System.ComponentModel.DataAnnotations;

namespace CustomValidation.CustomNameValidator
{
    //Inherited the base class ValidationAttribute to create our own Custom Attribute.
    public class CustomNameValidator : ValidationAttribute
    {
        private readonly int maxWords;

        //The constructor accepts single parameter i.e. maximum limit  to check the count of words. 
        //This can be used to validate FirstName to have specified number of words.
        //We are also passing a default message to base class. This is default message. 
        public CustomNameValidator(int maximumLimit)
            : base("{0} should be less than " + maximumLimit + " letters.")
        {
            //We are setting a private variable MaxWords with maximum limit which is specified while defining attribute.
            maxWords = maximumLimit;
        }

        //We have override the IsValid method which accepts value and ValidationContext object.
        //value is the input provided by user from Form. The value which is posted from form.
        //Validation context object has details about the property on which this attribute is used.
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            //Checking if the value is null.
            if (value != null)
            {
                //casting the object value to string.
                var valueAsString = value.ToString();
                //comparing the input value length and the length specified while defining attributes.
                if (valueAsString.Length < maxWords)
                {
                    //If the input length is within the maximum length allowed then attribute will return Success.
                    return ValidationResult.Success;
                }
                else
                {
                    //If the input length is not withing the maximum length, then error message is returned.
                    //As we have passed the default message above. We have passed a placeholder with it.
                    //The display name is passed as parameter. And error message is displayed.
                    var errorMessage = FormatErrorMessage(validationContext.DisplayName);
                    return new ValidationResult(errorMessage);
                }
            }
            else
            {
                //If value is null, we are returning error message. This validation works like Required attribute.
                //In below line we are passing display name and message as well.
                return new ValidationResult("" + validationContext.DisplayName + " is manadatory field");
            }
        }
    }
}


The above code validates the string input. It validates the input for its count. It also checks if value is null or not. The code returns the error message if validation fails.



How to apply :




        [CustomNameValidator.CustomNameValidator(40)]
        public string LastName { get; set; }

As per the above definition, the maximum string length allowed for LastName property is 40. If the value is more than 40, validation fails and error message is shown.



UI :


The validation message is shown if Last name length increases above 40.


Custom Data Annotations in Asp.net MVC3 Razor


Imagine you want to restrict the first name of the user to limited number of words. For example, you may say that 10 words are too much for a first name. Then in this case you can create your own Custom Annotation attribute.

Watch Video


       All of the validation annotations (like Required and Range) ultimately derived from the ValidationAttribute base class. The base class is abstract and lives in the System.ComponentModel.DataAnnotations namespace. Your validation logic will live in a class deriving from ValidationAttribute.



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

namespace CustomValidation.CustomValidator
{
    public class MaxWords : ValidationAttribute
    {
    }
}

To implement the validation logic, we need to override one of the IsValid methods provided by base class. Overriding the IsValid version taking a Validationcontext parameter provides more information to use inside the IsValid method. The ValidationContext will give you access to the model type, model object instance, and friendly display name of the property you are validating, among other piece of information.

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

namespace CustomValidation.CustomValidator
{
    public class MaxWords : ValidationAttribute
    {
        protected override System.ComponentModel.DataAnnotations.ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            return ValidationResult.Success;
        }
    }
}

The first parameter to the IsValid method is the value of the property to validate. If the value is we can return a successful validation result, but before you can decide if the value is valid, you will need to know how many words are too many. We can do this by adding a constructor to the attribute and force the user to pass the maximum number of words as a parameter.


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

namespace CustomValidation.CustomValidator
{
    public class MaxWords : ValidationAttribute
    {
        private readonly int _maxWords;

        public MaxWords(int maxWords)
        {
            _maxWords = maxWords;
        }

        protected override System.ComponentModel.DataAnnotations.ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            return ValidationResult.Success;
        }
    }
}

Now that we have parameterized the maximum word count, we can implement the validation logic to catch an error :

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

namespace CustomValidation.CustomValidator
{
    public class MaxWords : ValidationAttribute
    {
        private readonly int _maxWords;

        public MaxWords(int maxWords)
        {
            _maxWords = maxWords;
        }

        protected override System.ComponentModel.DataAnnotations.ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                var valueAsString = value.ToString();
                if (valueAsString.Split(' ').Length > _maxWords)
                {
                    return new ValidationResult("Too many words !!");
                }
                else
                {
                    return ValidationResult.Success;
                }
            }
            else
            {
                return new ValidationResult("No Value supplied !!");
            }
        }
    }
}

We are doing a relatively naive check for the number of words by splitting the incoming value using  the space character and counting the number of strings the Split method generates. If you find too many words, you return a ValidationResult object with a hard-coded error message to indicate a validation error. 
                         The problem with the last code is the hard-code error message. Developers who use the data annotations will expect to have the ability to customize an error message using the ErrorMessage property of ValidationAttribute.
                         To follow the pattern of the other validation attributes, you need to provide a default error message (to be used if the developer does not provide a custom error message) and generate the error message using the name of the property you are validating :


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

namespace CustomValidation.CustomValidator
{
    public class MaxWords : ValidationAttribute
    {
        private readonly int _maxWords;

        public MaxWords(int maxWords)
            :base("{0} has too many words !!")
        {
            _maxWords = maxWords;
        }

        protected override System.ComponentModel.DataAnnotations.ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value != null)
            {
                var valueAsString = value.ToString();
                if (valueAsString.Split(' ').Length > _maxWords)
                {
                    var errorMessage = FormatErrorMessage(validationContext.DisplayName);
                    return new ValidationResult(errorMessage);
                }
                else
                {
                    return ValidationResult.Success;
                }
            }
            else
            {
                return new ValidationResult("No Value supplied !!");
            }
        }
    }
}

We made following changes in preceding code :


  • First, we pass along a default error message to the base class constructors. You should pull this default error message from a resource file if you are building an internationalized application.
  • Notice how the default error message includes a parameter ({0}). The placeholder exists because the second change, the call to the inherited FormatErrorMessage method, will automatically format the string using the display name of the property. FormatErrorMessage ensures we use the correct error message string. The code needs to pass the value of this name, and the value is available from the DisplayName property of the ValidationContext parameter. With the validation logic in place, you can apply the attribute to any model property. 
        [Required]
        [MaxWords(20)]
        public string FirstName { get; set; }

We could also specify the error message to show.


        [Required]
        [MaxWords(20,ErrorMessage="There are too many words in {0}")]
        public string FirstName { get; set; }

Now if the user types too many words he will see the error message on UI.
Thus inheriting the ValidationAttribute class, we can create custom annotation attribute.

Custom Validation Data Annotation Attribute in Asp.net MVC3



1. We can create custom Data Annotation attribute, same as we use other DataAnnotation attributes.
2. To create custom Validation attribute, we need to inherit ValidationAttribute class.
3. We need to override IsValid() method of ValidationAttribute class.
4. By creating custom logic for validation attribute we can create attribute which will work and check conditions the way we want.

Watch Video



In order to see how to create DataAnnotation Validation attibute and how to use them, we need to have a form and a model class.
We have following form, a register model class and controller methods ready as shown below.

Model Class :





The above is the register model class. We are going to create a form which will contain the properties declared in the model class. And we are going to apply Validation attribute in this model class itself.


View :



This is our form. We are using helper EditorForModel() to create container for all properties of Register class. On submit form is posted to Welcome method in the controller.


Controller :



This is our controller. In the Welcome Action Method where our form data is posted, we are checking whether ModelState is valid or not. If it is valid then we are returning Welcome view else we are returning Index view with register class's object along with model errors.

ValidationAttribute Class :

We are going to create a separate folder to hold our CustomValidationAttribute class as shown below.



Inside the folder we added a class. As we are going to create a Custom validation attribute to validate FirstName property, we name the class file as FirstNameValidator.




In order to create custom validation attribute we need to add reference of ComponentModel.DataAnnotation. We have inherited ValidationAttribute class and override or used its IsValid method. 
           IsValid method accepts two parameter. One is the value of the property from the form and other is the ValidationContext object, which contains information about property.
This IsValid method returns ValidationResult, either success or validation error.
           In the above class, inside first if block we are validating whether user has entered value for FirstName or not. If user has entered the value then we are returning success else we are returning error message.
           In the second if block, we are checking the length of the FirstName whether it is less than 20 letters or not. In this way we can apply as many conditions or validations we want.








In order to use the custom attriute we created, we need to include namespace in our register class as shown above i.e (using CustomValidtionAttributeInMvc3.Validators;). And we will apply FirstNameValidator attribute to FirstName property as shown
above in the same manner we use to do it for other DataAnnotaions property. When you run the application and check it validates the user input accordingly.





This is the Form rendered. We input nothing and submit the form.




We get validation message for FirstName, as we have created and applied custom Validation attribute for FirstName.




Here we get validation message for input greater than 20 letters.


Points To Remember :

1. We can create our own Validation attribute using validationAttribute class and DataAnnotation.
2. We need to inherit ValdiationAttribute class and override its IsValid method.
3. These custom attributes can be used same way as we use other in built DataAnnotation attribute.


You may also like to view: