19 July 2012

MVC Data Annotation Validators - The Problem

This "Problem - Solution" is a two series article . So this is the first: The Problem.

Validating objects through metadata is the approach of Validation with the MVC Data Annotation concept.
Metadata allows us to bind specific configurations to the business objects without changing or extending any of the objects implicit responsibilities.
In ASP.NET MVC, the concept is to use a specialized view model for each view and to pass the data needed. In this approach, the validation attributes must be placed in view model class.
If you have a separation between each layer of the application, and that separation implies that you have different projects for each layer. The model can be defined by the classes generated by the entity framework in you data access layer or by your business layer.

I have a database first approach using the Entity Framework and to use the MVC validation I could create a partial class with a MetadataType attribute to define the validator class. This is called a "buddy class".
A simple example is:
[MetadataType(typeof(CustomerMetadata))]
public partial class Customer
{
    // Class generated by the Entity Framework designer
}

public class CustomerMetadata
{
   [Required]
   public object Id;

   [Required]
   [StringLength(250)]
   public object FirstName;
}

The above approach works great, but if you have service oriented architecture with WCF Services the validation attributes will be ignored by the WCF Serializer.
The reason is obvious, the service and operation contracts are described by the Web Service Definition Language (WSDL), but the W3C specification doesn't support these attributes, so they are simple are ignored.

Possible solutions to this problem are:
1) Using buddy classes for partial classes of the WCF proxy
2) Share an assembly with your entities between your WCF client and WCF service and reuse those types

None of the above solutions are what I consider a good option and both will create tight coupling between your service and ASP.NET MVC application.

Another problem I face is that I have a project with all my service Proxies that is referenced by the MVC application or any client.
Since you cannot have two partial classes referring to the same class in two different assemblies (projects) and I don't want to have MVC specific client side validation on my reusable proxy library, so another solution is in order.

Above all i think that if you want to have client side validation you should to it on the client side.
The validation must be as simple as defining some rules that don't need to be associated directly with your model class.

I also wanted to take advantage of all the MVC validation infrastructure with client and server side validation. I don't want to reinvent the wheel and develop all that code manually.

The solution I found is to use Fluent Validation framework with an Inversion of Control container (IoC) to instantiate my validators.
The Inversion of Control (IoC) pattern is all about removing dependencies from your code.
Fluent Validation is a small validation library for .NET that uses a fluent interface and lambda expressions for building validation rules for your business objects.
This post explains the problem, on my next post I will explain the implementation of Fluent Validation with MVC as the solution.

Meanwhile if you can't wait, you can read about the fluent validation here

No comments: