Custom Validation with IValidatableObject in MVC
In
this post you will learn how to create a self validatable object using
IValidatableObject to validate data in MVC.
Let’s look at a situation where we will implement IValidatableObject to enable date validation.
Let’s look at a situation where we will implement IValidatableObject to enable date validation.
In
the above form, you can see Date of Birth is in future which is wrong from
every prospective. So to validate this date we can implement
IValidatableObject, let’s see how.
Now,
follow the steps from here.
Step 1
Open
model and implement interface IValidatableObject. You can get this popup by pressing Ctrl+. (dot). It implements validatable interface automatically in Visual Studio.
When
you click on ‘Implement interface ‘IValidatableObject’ you will have following interface.
This will return IEnumerable<ValidationResult> by taking one parameter as
ValidationContext.
Step 2
Now,
inside above context we can implement our validation checks as given below.
In
above self-validation context I have implemented two checks. First, is date in future?
Second, is date in too past? If condition matches will return the validation
result.
Step 3
Run
the application and test it. It will work fine with two unavoidable bugs.
First,
the newly added validation will only work when you click the button however it
should immediately report the error if selected date is in future or too past.
Second,
the validation error message should be displayed with the Date of Birth
textbox.
Step 4
Actually
by default every error message get placed here (in the image below) and this is
the reason we are getting error message on the top.
Also,
the reason of this error is that we didn’t associated the returned validation
result with appropriate property in the model.
Step 5
To
associate the model property with validation result, let’s make following
changes.
Created
a variable which will contain list of model properties because ValidationResult
only accepts IEnumerable data (look at the intellisense in above image) and the reason is a ValidationResult can be
applied to multiple model properties.
Now,
if you run the application at this point you will see everything working.
Awesome.
Note: Thanks to Joy (a reader of this blog entry) who commented right below to mention this. IValidatableObject method only be called when all the property validation has passed.
Hope this helps.
Hope this helps.
Great work Abhi, useful.
ReplyDeleteWhat you havent mentioned is . This Validate method would only be called when the property validation has passed . By default it would never trigger validate it . I just reproduced that issue on my system
ReplyDeleteThanks Joy. I really forgot, going to put a note at the end in post.
DeletePlease don't post screenshots with code. Use some free plugin to post code samples (for example syntaxhighlighter). Cheers.
ReplyDeleteFabulous effort Abhimanyu, cheers!!!
ReplyDeleteIt is working on the Server side so can we done it through client side
ReplyDeletesimple to set 'maxDate:new Date' you cannot select future date.
ReplyDeleteexample: $('#gfrom').datepicker({ maxDate:new Date, changeMonth: true, changeYear: true });
Very nice article.Thanks
ReplyDeleteGood one but here's a question, what if you need the model property to be nested, eg FormerAddress.AddressLine1?
ReplyDelete