In the first article (Validation Techniques Comparison) we just considered the most useful and the best techniques that could be used for validation implementation in ASP.NET MVC.
We don’t want to deprive you of a pleasure of doing all this by yourself, so we will just give you a direction and some samples of implementation and let you dig deeper .
So, today’s agenda is:
- Manual validation in Model Binder and Controllers (client validation type 1 and server validation type 1)
- DataAnnotations (client validation type 2, server validation type 2);
- Custom Validation engine implementation (client validation type 1, server validation type 2);
- Spring Validation Framework usage on a server, manual validation on a client (client validation type 1, server validation type 3)
- Spring Validation Framework usage on a server, DataAnnotations + manual validation on a client (it’s a mix from several points from previous review);
- xVal Validation Framework
Manual validation in ModelBinders and ControllersWhen we started working with ASP.NET MVC some time ago it was almost the only solution we could implement. It’s obvious and could be ascribed to the brute-force approaches family.
The essence of this approach is that you just male your validation completely manually in controllers and everything is in your hands: from how to define validators (actually you don’t have them – you just right rules as a code) to how to show validation errors and how to merge server-side and client-side validators.
Whereas it’s the simplest solution to start from it’s not a good practice for real projects – too much of coding, less code reuse, mixing of logic or binding and validation. It could lead to some kind of mess in code and horror in the future maintenance.
So, just don’t keep in in your mind and move forward.
DataAnnotationsIt’s a built-in validation provided along with ASP.NET MVC. And this approach is widely boosted on the Internet as a default validation solution for ASP.NET MVC projects.
Additional information about this approach and good its description could be easily found, and these articles could be good starting points:
Validation with the Data Annotation
DataAnnotations and ASP.NET MVC
ASP.NET MVC Tip #43 – Use Data Annotation Validators
We also bought that on one of our projects and had started implementation with DataAnnotations and, what was the surprise , almost immediately had faced with the following problems:
- Shortage of validators.
- Relations between validators are hardcoded;
- There is no possibility to define group of validators or dependencies between some validators.
- It’s not easy to extend the framework with new validators.
Custom Validation implementationASP.NET MVC provides good extensibility point since Version 2 Preview 1. Unfortunately, there is not much documentation about this approach but this question on stackoverflow - ASP.NET MVC 2 - Implementing custom Metadata and Validator Providers – could be a good starting point.
So, if you have some time you can definitely implement your custom solution where you will develop all the things you need, any kind of validation, integration, interface and so on and so force. And may be you even will be in time with your project. Or at least validation part of the project. My decision was to wait a little bit for third-party implementations or at least some templates that will allow me to just extend them not doing all the work from scratch.
Spring Validation FrameworkAs I already wrote Spring.Net Validation Framework (http://www.springframework.net/doc-latest/reference/html/validation.html) is a standard de-facto in our company for many reasons. And I still don’t want to argue about this choice. (But, I’d be glad to hear something new about other validation frameworks and may be I will agree with you later).
So we tried to integrate ASP.NET MVC and Spring.Net. And, wow, it’s possible and easy!
Firstly, we tried to implement the integration through Validation and Metadata Providers. But, unfortunately they are oriented to step-by-step validation of the object’s properties. That is bad, because it doesn’t allow us to use all the power of validation framework and not in-line with it.
Then we used OnActionExecuting method in the following way:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
// 1. Need to validate model only for the post requests
if (filterContext.HttpContext.Request.HttpMethod == "POST")
// 2. We pass through the parameters of actions to obtain objects for validation.
foreach (KeyValuePair<string, object> keyValue in filterContext.ActionParameters)
// 3. Obtain validator by its name.
BaseValidator validator =
SpringSingleton<BaseValidator>.GetInstance(keyValue.Value.GetType().Name + "Validator");
ValidationErrors validationErrors = new ValidationErrors();
// 4. Validating...
if (!validator.Validate(keyValue.Value, validationErrors))
// 5. Transform Spring validation errors into ModelValidationResult objects.
foreach (ModelValidationResult modelValidationResult in GetModelValidationResults(validationErrors))
// 6. Add error to the list of errors.
Of course, it’s just a sketch. What we did:
- We decided to validate only the POST requests.
- We analyze an action on the subject of parameters it takes. Every parameter is considered as the object that could be validated. Thus we take every parameter and pass it through the validation cycle.
- Here is the simplest solution for validation :) Of course in a real-world project you should implement your own solution for obtaining validation rules by model (or by whatever else). We just define naming convention that validation rules are registered with names postfixed with “Validator” for every object.
- We ask validation engine to validate the object
- We transform Spring validation errors into standard built-in ModelValidationResult objects.
- And add these objects to the errors list.
You will also need to implement a mechanism of making a choice of which object should be validated on which actions and by what rules (steps 2 and 3). There are several variants that are possible:
- You can mark a model that this model should be validated;
- Mark an action, that some of its parameters (models) should be validated (and additionally you can define – by which validator);
- Mark a controller for more flexible validation;
- Move configuration and links specification into separate configuration file (e.g. XML-file)
Spring Validation + DataAnnotationsPrevious solutions will force us to use manually written validation on client (or some other framework). And here an interesting question arises: how many complex checks do we have? If we have not many of them then why should be spend our implementing the functionality which we could easily get from standard implementation (I mean DataAnnotation). We have not more than 30% of complex validation rules from the overall quantity of valiadtors to be implemented. Please, agree, all we are too lazy to implement the rest of them (70%!) manually.
So we have decided to try DataAnnotation only for the client validation and Spring Validation Framework for the server one.
And this mix is our choice and recommended solution – it’s easy to define server rules using XML definitions or code (use what you want, Spring allows you to do it) and to define the most of client checks using attributes not Java Script
xVal Validation FrameworkOn one of our projects we tried to use xVal Validation Framework.
It is an interesting solution, an interesting framework.
Actually, it was…
Why so? ASP.NET MVC 2 provides very similar mechanisms to what xVal provides. If you are going to use ASP.NET MVC 2 on your project then all the possibilities which are provided by xVal now are provided by ASP.NET MVC infrastructure: DataAnnotations, IRulesProvider (analogue is ValidatorProvider + MetadataProvider). Correspondingly, there is no much sense to use xVal for the projects based on ASP.NET MVC 2.
But still it’s a good framework anyway :)
ResumeWe have tried several options. All these options are described in this article. And we have found that Spring Validation Framework + Data Annotations + jQuery is the most powerful, flexible and time-saving choice on our projects.
Your choice is definitely could differ from our one. And we’d like to here your arguments and to see your implementation ideas.
Enjoy your job!