Custom Data Annotations or Custom Validation Attributes in MVC
In
this post you will learn how to create custom data annotation in MVC. MVC
framework has great extensibility feature and because of this we can create our
own customized data annotation attributes.
Let’s assume, we don’t want user to enter /.,!@#$% (we can add more characters anytime no further changes needed) characters or symbols with his name.
I have recorded a video on this title, you can watch it.
To
do this we have following alternatives:
Both
ways given above has some limitations, they can’t let us validate data out-of-box
for example, with IValidatableObject there is no value (data entered by user in
textbox) parameter passed to validate. With validating data in controller
action, we can’t reuse it throughout application and much more.
So,
here we are going to create our custom data annotation attribute like Required,
MaxLength(10) which we frequently use. Please note, with MaxLength(10)
annotation we can pass value as a parameter to validate. And also these
annotations can be used anywhere in the application.
Here
is the image of what we are going to create.
In
the above image, you can see I have used [ExcludeChar(“/.,!@#$%”)], which is
nothing but a custom data validation attribute used with Name property. You can
also see, when one entering any character defined with the parameter of
ExcludeChar in textbox, it displays model validation error.
Now
follow the steps to create this.
Step 1
Add
a class ExcludeChar in the project. As you know, all of the validation
annotations (like Required, Range, MaxLength) ultimately derive from the
ValidationAttributebase class. So we will derive ExcludeChar class as well.
public class ExcludeChar : ValidationAttribute
{
....
}
Step 2
To
implement custom validation logic, we need to override one of the IsValid methods
provided by the base class. IsValid method takes two parameters, first one is ValidationContext
which gives access to the model type, model object instance, and friendly
display name of the property you are validating, among other pieces of
information. Second, value of Object type which is nothing but the information
or string typed by the user in textbox.
public class ExcludeChar : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
....
return ValidationResult.Success;
}
}
If
the value is valid we can return a successful validation result, but before we
can determine if the value is valid, we’ll need to know is there the any matching
character from the set of /.,!@#$%.
Step 3
So
far we have the value typed by the user in IsValid method but we don’t have the
list of characters (/.,!@#$%). We can do this by adding a constructor to the ExcludeChar
class, this constructor will accept string which is the set of characters
(/.,!@#$%), this string will be initialized to a local private variable _chars.
Also, constructor will assign the default error message to the base class.
public class ExcludeChar : ValidationAttribute
{
private readonly string _chars;
public ExcludeChar(string chars)
: base("{0} contains
invalid character.")
{
_chars = chars;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
....
return ValidationResult.Success;
}
}
Step 4
Now
the last thing, implement the validation logic to catch an error:
public class ExcludeChar : ValidationAttribute
{
private readonly string _chars;
public ExcludeChar(string chars)
: base("{0} contains invalid
character.")
{
_chars = chars;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value != null)
{
for (int i = 0; i < _chars.Length; i++)
{
var valueAsString = value.ToString();
if (valueAsString.Contains(_chars[i]))
{
var errorMessage =
FormatErrorMessage(validationContext.DisplayName);
return new ValidationResult(errorMessage);
}
}
}
return ValidationResult.Success;
}
}
Very
simple logic, first making sure passed value (typed by the user in textbox) is
not null if so go ahead and check is value contains any of the _chars. If
success to find any match, immediately returns the base error message.
Step 5
Now,
go ahead the use this newly created data annotation [ExcludeChar(pass the set
of chars)].
Use
any of the following data annotation attribute throughout your application.
//
simple annotation attribute
[ExcludeChar("/.,!@#$%")]
//
overriding the error message of data annotation attribute
[ExcludeChar("/.,!@#$%",
ErrorMessage="Name contains invalid
character.")]
//
overriding the error message by localized message
[ExcludeChar("/.,!@#$%", ErrorMessageResourceType=(typeof(MvcApplication1.Views.Demo.ABC)), ErrorMessageResourceName="YourResourceName")]
You
can see how easy it is to create and use. Now, open VS and create one yourself
and let me know your experience.
Hope
this helps.
i try to run this code in VS 13 and MVC 5 and try to debugging with a breakpoint but not call the method "IsValid", something changed in this version? can you help me? greetings
ReplyDeleteHi, Can you please confirm the s/w versions, where this code works?
ReplyDeleteMVC version
jquery scripts to be included with thier versions
Visual studio version
Thanks in advance.
Hi,
ReplyDeleteCan you please confirm the s/w and their versions, where this code works.
MVC
jquery includes
Visual studio version
and any other
Thanks in advance,
I have tried with vs 2012 and mvc 4. It is working fine
ReplyDeleteThanks lot for this great expalnation
excellent !
ReplyDeleteEasy to understand and I can create custom annotations within 10 minutes. Thank you.
ReplyDeletegood
ReplyDeleteVery crisp and comprehensive tutorial
ReplyDeleteSimple and perferct illustration.
ReplyDeleteThanks.
This does not work. One .Contains() must be a string so you have to say _chars[i].ToString() and even after taking everything you had in a fresh MVC 4 project it does not work - it completely ignores everything.
ReplyDeleteyou add Unobstrotive js in your View
DeleteIt is not displaying error message on client side :(
ReplyDeleteThank you for such a wonderful Article. Sir, if you write an article on how to give validation group in MVC ..then i rfeally appreciated.Thanks in Advance.
ReplyDelete