Custom Validation in ASP.NET MVC 3 using DataAnnonationsModelValidator

Posted by: Mahesh Sabnis , on 12/5/2011, in Category ASP.NET MVC
Views: 125236
Abstract: In this article, I will demonstrate how to implement custom user defined validation rules in ASP.NET MVC3. MVC 3 being an extensible framework, makes it possible for the developer to add user defined specific custom validations using custom data annotations.
In this article, I will demonstrate how to implement custom validation rules in ASP.NET MVC3. MVC 3 being an extensible framework, makes it possible for the developer to add user defined specific custom validations using custom data annotations.
 
Consider the scenario where you are developing an application for Loan processing system. Your system asks customer to enter details like Name, Salary etc. Now for processing loan, a rule is that the Salary must be greater than or equal to Rs.20000/- (equivalent to $450). A common scenario would be to provide feedback to the end-user so that the moment a salary below 20000/- is entered and user tries to submit, an error message gets displayed on the screen. 

 


To implement Custom validation and apply it using Data Annotations, your class must inherit from ‘ValidationAttribute’ class. This class is the base class for all standard data annotations types e.g. RequiredAttribute, RangeAttribute etc.

Step 1: Open VS2010 and create a new ASP.NET MVC 3 project. Name it as ‘ASPNET_MVC3_Custom_ModelValidation’.

Step 2: Add a new folder in the project, name it as ‘CustomizedValidators’. In this folder add a new class file, name it as ‘CustomValidator.cs’. This class file will contain the custom validation class and the data annotations class. In this class file write the following code as shown below:

mvc-custom-validators
Note: Please read the comments given in the code to understand what each method does .

The SalaryAttribute class is inherited from ‘ValidationAttribute’ class. The SalaryAttribute class overrides the ‘IsValid()’ method of the base class. This method returns an object of ‘ValidationResult’ class. The ValidationResult class represents  acontainer for the result of validation request. The method currently implements validation on the ‘_MinSalary’ member. Here if the Salary entered by the end-user is less than a specific amount (Rs. 20000/- in this case), then an error message will be shown because the ValidationResult class will not return ‘Success’ back to the UI.

The ‘SalaryValidator’ class is inherited from DataAnnotationsModelValidator<T> class. This class provides a model validator for the specific type. The method ‘GetClientValidationRules()’ is used to define client validation rules against the specific field.

Step 3: In the Model folder, add a new class file and name it as ‘ModelClasses.cs’. Add the following model classes in it:

mvc-custom-model

In the ‘Customer’ class locate the ‘Salary’ property. The ‘Salary’ attribute is applied with the salary value as 20000 in the constructor.

Step 4: Add the CustomerController in the Controllers folder with the following code:

mvc-custom-validation-controller

The Create() method with HttpPost attribute defines the logic for creating a new customer by making calls to ‘CreateCustomer()’ method of the DataAccess class. The logic checks the Model State using ModelState.IsValid condition which validates whether the model state dictionary is valid or not.

Step 5: Add the Index and Create views by right-clicking on the Controller methods e.g. Index and Create (without HttpPost attribute). Select the Model-Class for the views as Customer.

Step 6: Make the following changes in the ‘_Layout.cshtml’ file in the Shared folder:
<li>@Html.ActionLink("Customer", "Index", "Customer")</li>

Step 7: Run the application and click on the ‘Customer’ tab. The Customer Index will be displayed as below:

customer index
Click on the Create New link and the Create view will be displayed as shown below:
Create New Customer

Enter values for CustomerName and City, keep Salary value as default and click on Submit. The result will be as shown below:

MVC Custom Validation

Note the error message that gets displayed.

Conclusion: Since ASP.NET MVC 3 is an extensible framework, it provides a flexible mechanism for Model validations. The advantage of creating a separate validation attributes class is that it can now be reused across various models as per the requirements.

The entire source code of this article can be downloaded over here

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Mahesh Sabnis is a DotNetCurry author and a Microsoft MVP having over two decades of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions), and Front-end technologies like Angular and React. Follow him on twitter @maheshdotnet or connect with him on LinkedIn


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Shmit on Friday, December 9, 2011 10:48 PM
Thanks for this article Mahesh. I regularly read all your articles :)
Comment posted by Mahesh Sabnis on Wednesday, December 21, 2011 5:16 AM
Hi Shmit,

Thanks a lot.
Regards
Mahesh Sabnis
Comment posted by Awadhendra Kumar Tiwari on Sunday, April 1, 2012 2:36 AM
Hi Mahesh,
Nice approach, you explained very well about validation in ASP.NET MVC3. I am a new learner in ASP.NET MVC3 and this article is great helpful for me. I learned about validation and I compare it from ASP.NET then I found that it is very easy to implement it in MVC. We can implement it in one place and it react in both place which is server side and client side. It's really good to know it. I had explained few basic things about validation in ASP.NET MVC3 using razor view engine at following url

http://dabbu-csharphelp.blogspot.in/2012/01/validation-in-asp.html

I think this is useful for beginners who wnt to know basic of validation in ASP.NET MVC3. Thanks for sharing such a useful articlde on validation.

Thanks.
Comment posted by Mahesh Sabnis on Wednesday, April 25, 2012 10:47 PM
Dear Awadhendra Kumar Tiwari
Thanks a lot.
Your article is also Really Nice.
Regards
Mahesh Sabnis
Comment posted by Mubashir Qureshi on Wednesday, May 8, 2013 12:57 AM
This is very nice artical as beginers like me helps alot to get idea about validation
Comment posted by Rinkal Patel on Tuesday, August 19, 2014 5:53 AM
   [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
        public sealed class CCompareAttribute : ValidationAttribute, IClientValidatable
        {
            private const string _defaultErrorMessage = "Confirm password should match with password field.";
            private readonly int _minCharacters = Membership.Provider.MinRequiredPasswordLength;
            private string name;

            public CCompareAttribute(string compare)
                : base(_defaultErrorMessage)
            {
                name = compare;
            }

            public override string FormatErrorMessage(string name)
            {
                return String.Format(CultureInfo.CurrentCulture, ErrorMessageString);
            }

            public override bool IsValid(object value)
            {
                string valueAsString = value as string;
                return (valueAsString != null);
            }

            public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
            {
                return new[]{
                new ModelClientValidationEqualToRule(FormatErrorMessage(metadata.GetDisplayName()),name)
            };
            }
        }




        [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = false)]
        public class TypeErrorMessageAttribute : Attribute
        {
            public string ErrorMessage { get; set; }
            public string ErrorMessageResourceName { get; set; }
            public Type ErrorMessageResourceType { get; set; }

            public TypeErrorMessageAttribute()
            {
            }

            public string GetErrorMessage()
            {
                PropertyInfo prop = ErrorMessageResourceType.GetProperty(ErrorMessageResourceName);
                return prop.GetValue(null, null).ToString();
            }
        }