It seems that when MVC validates a Model that it runs through the DataAnnotation attributes (like required, or range) first and if any of those fail it skips running the Validate method on my IValidatableObject model.
Is there a way to have MVC go ahead and run that method even if the other validation fails?
There's a way to do it without requiring boilerplate code at the top of each controller action.
You'll need to replace the default model binder with one of your own:
Your model binder provider looks like this:
Now create a custom model binder that actually forces the validation. This is where the heavy lifting's done:
You'll need an IndexOf extension method, too. This is a cheap implementation but it'll work:
You can manually call Validate() by passing in a new instance of ValidationContext, like so:
A caveat of this approach is that in instances where there are no property-level (DataAnnotation) errors, the validation will be run twice. To avoid that, you could add a property to your model, say a boolean Validated, which you set to true in your Validate() method once it runs and then check before manually calling the method in your controller.
So in your controller:
And in your model: