Validations with WCF and JSON

Earlier I discussed getting WCF to work with JSON, and I wanted to talk a little more about validations.  I prefer attribute based validations for simple domain constaints and code validations for more complex validations.  The Validation Application Block (VAB) in the Enterprise LIbrary provides a great solution for validation.  While I think a lot of pieces of the Enterprise Library are a little too complex and poorly documented (i.e. ObjectBuilder), I really like the VAB.

 

VAB ships with integration for WCF.  It allows you to define attribute based validations on your service parameters like (I am borrowing this example from http://blogs.microsoft.co.il/blogs/bursteg/archive/2007/04/06/11506.aspx):

 

[ServiceContract]
public interface IOrdersService
{
    [OperationContract]
    int CreateOrder(
        [NotNullValidator] string currency,
        [RangeValidator(1.0, RangeBoundaryType.Inclusive, 2.0, RangeBoundaryType.Inclusive)] double amount);
}
 

Now, when you call the CreateOrder method on the service, it will validate the parameters and make sure that currency and amount follow the specified validations.  Unfortunately, their are two limitations with the out of the box approach.  One, you cannot define validations using the Enterprise Library configuration (which I do not prefer but I can see how it is beneficial in some scenarios).  Second, the default WCF integration handles the validations by throwing a Fault that contains the validations details.  This does not play well with ExtJS because it expects a successful AJAX requests that contains a message specifying that there were validation errors.

 

I researched a couple of different ways to alter the out of the box integration.  Unfortunately, the out of box integration uses IParameterInspector which only allows you to inspect parameters as they are coming into the the service.  I come across a little discussed extension point of WCF called IOperationInvoker.  IOperationInvoker allows you to do before and after interception of WCF service calls.  The mean benefit of this is that it allows me to return validation error messages as a successful result or a service call through a defined contract like:

[ServiceContract]
public interface IOrdersService
{
    [FormValidation]
    [OperationContract]
    FormResult CreateOrder(
        [NotNullValidator] string currency,
        [RangeValidator(1.0, RangeBoundaryType.Inclusive, 2.0, RangeBoundaryType.Inclusive)] double amount);
}

 

Note the attribute [FormValidation] on the service.  This instructs the WCF service host to use the IOperationInvoker that I defined for the service.  I also llike this approach because I do not have to define the validation behavior in XML, and can instead decorate my service.  My FormResult object contains three properties: Successful(), Errors (which returns ValidationDetails[]), and Result (which returns the actual result). 

 

Although I did not implement my IOperationInvoker this way, I believe that you can also return the ValidationResults as an out parameter if you prefer that method signature style but I am not sure how/if this works with WCF REST services.  Also, this approach can be integrated with validations configured in XML. 

 

Ff you do not want to be tied to the Enterprise Library, you should be able to apply this approach to other frameworks.  Castle has a validation component that has similar functionality to the VAB.

 

Here is a link to the source.