IntroductionWhen you start development using new technology or framework several questions are arisen: how does it support work with RDBS, how to implement UI better etc.
And, of course, – Validation.
There are several solutions on how to implement validation in the projects based on ASP.NET MVC. When our company first time faced with the ability to implement a solution based on this technology we made an analysis of all viable possibilities. This article and some upcoming articles are the results of those investigations. In this, first article we will consider more theoretical questions and just consider why we have chosen this or that approach in validation. In the next article we will consider implementation of different approaches.
First of all we split validation into two parts- client- and server-side validation and looked at the implementation possibilities and their proc and cons.
There are two common approaches in client validation: separate client-side validation and client-side validation based on the same rules as server-side one.
Separate client- and server-side validationsClient validation is performed using pure Java Script or jQuery (or may be other your favorite framework, we will stop a little bit on choice of them later) without any technical links (as common files, common rules etc) to the rules used in server validation.
- You may perform almost any complex validation quite easily without converting business rules written on special language or in special format (for example – XML or DataAnnotations);
- You don’t need to define common mechanism of how to show the error – you may process error in a way you want: highlight one field, show window – for another etc;
- Client validation duplicates server one to some extent. In this case you need to do work work twice. Sometime it could be not a big problem if you have some amount of validators written and implementation of client side validation just boils down to inserting such validators;
- Maintenance problems. You need to support this code. And when you remove validation you need to remove it in two places.
- Testing problem. Client-side validation is hardly tested with usual unit-tests.
Validation based on the server-side validationThis kind of validation is based on the rules defined for server-side validation. These rules can be described in XML (e.g. Spring.Net Validation), attributes (e.g. DataAnnotation) or another way. The idea is two have just one storage of validation rules but use this storage on every layer of the application.
- There is no duplication of checks on server and client – we have just one place for this;
- All validation logic could be abstracted from UI and business-model of application (in metadata);
- Validators could be covered by tests.
- Maintenance is better – because you need to change the rule only in one place.
- Lack of good implementations. Yes, idea is very good and beauty. But there is no many frameworks that could be used with such approach. For example, DataAnnotations which is supported in ASP.NET MVC 2 Preview 2 has not a big amount of validators. And their implementation is not so good as wished. And even on the small projects it leads to that the client validation couldn’t be placed in one place and developers have to spread it among the different parts which makes support much more harder.
- Implementation of different UI behavior is harder. If you want to, for example, show different validation messages in different formats and places using different techniques (uniqueness errors - in a message window, incorrect format – via asterisk etc) than you will face with poorer extensibility and customizability of existing frameworks.
ConclusionSo, despite on the fact that second approach is more attractive and seems better in reality there is no good framework yet that could conform the most of our requirements.
That’s why we have chosen first approach for our project and as practice shown we had made a good choice. Complexity of validation rules and links between fields and different object wouldn’t allow us to implement it just using DataAnnotations.
But may be in the nearest future this mechanism will be improved a lot and we will finally obtain the tool that could be used in the real-world projects in full power and become a real time-saver.
Server-side validationThere are three most common approaches to the server-side validation in ASP.NET MVC:
- Validation in Model Binder or Controller;
- ValidationProvider and MetadataProvider usage (since ASP.NET MVC 2);
- Third-party validation framework usage.
Validation in Model Binder or ControllerPros:
- Demands the least qualification requirements to programmer - no need to know about additional libraries and peculiarities of ASP.NET MVC architecture;
- It’s not so hard to implement complex checks;
- Rigid bond between logic and validation. No clean separation of concerns;
- Validation is actually hardcoded into the Controllers and Binders thus making maintenance harder;
ValidationProvider and MetadataProvider usageYou can customize validation mechanism by implementing you providers. ASP.NET MVC 2 by default proposes to use DataAnnotationValidationProvider and DataAnnotationMetadataProvider. So, let’s consider this out-of-the box option with extensibility in mind.
- Declarative definition of validation rules.
- Automatic support of client-validation if it is based on the same rules as the server one.
- Extensibility of validation. You can implement your Validation engine based in Validation Provider and/or MetadataProvider;
- Validation checks could be covered by tests;
- Currently the set of supported validation attributes are not so wide as desired. Even on small projects it leads to the situation when validation could be implemented by attributes only and we need to implement “manual” validation in ModelBinders or Controllers. Thus validation is spread across application.
- This mechanism was initially developed for validation of separate properties of the object but not the object in whole. Correspondingly it’s problematic to implement complex validation of 2 and more bound fields of the object (for example, password and his confirmation which should be analyzed for security, ‘requiredness’, and equality);
Third-party validation framework usageI won’t discuss about which Validation framework is the best. We have using Spring.Net for several years and it almost completely satisfies our requirements. It’s a standard de-facto in our company so there was no question what framework to use in this approach.
- Separation of concerns. Validation logic is separated from application business logic.
- Possibility to define validation rules without recompilation.
- Validation rules could be separately tested (e.g. in unit-tests)
- Validation rules could be reused.
- We have distinct place for all the validation staff.
- Localization becomes easier.
- We need to design application taking into account Spring framework usage (hey, but when do you design your application not keeping in mind what could you use?). Anyway, we can use abstraction layers and IoC to encapsulate validation logic in separate part of application and just use it, and if necessary – to replace by better framework.
- Requires a little bit more of learning. But if you already have your favorite framework – this is mostly not about you.
- Duplication of client and server-side validation.
ConclusionAfter thorough analysis of all these pros and cons we had decided to stop on third approach. So finally we separate validation into two places – jQuery validators on client and Spring.Net validators on server. It leaded to some duplication but allowed us to reuse our knowledge and to implement validation of any kind of complexity. Also, maintainability of our application is very good and validation actually not our pain on the ASP.NET MVC projects.
What’s the next?In our next article we will stop on particular implementation of different approaches which will allow you to understand our choice better and may be make your own, different, choice and start development of it.
Vote on DZone: http://www.dzone.com/links/advanced_validation_techniques_in_aspnet_mvc.html