Tuesday, February 11, 2014

Enterprise Library Validation integration with WCF

Validating your data contract using Validation block of Enterprise Library 6


I like what I do. Every day a new challenge of something or other which you have to overcome. You will never know where you might stuck today and by the end of the day you would have probably learnt something new.

So, today's requirement was to validate my data contract before any of my method in WCF service do anything. I would probably bore you a little bit more in explaining how I came up with such requirement although it is not something very rare.

We have a website hosted on Windows Azure which collects user data and calls a WCF service which further pushes that on to a Storage queue. From there a dedicated Windows Azure worker role picks that up and send the data into CRM. Now sometime in future, we are going to get rid of the front end web application and hence all data validation logic needs to be present on the data contract as well and here is the requirement for today's research.

Having said that lets start with what we have to achieve. In order to validate data contract using Enterprise Library validation you have to make changes at four different places.
  1. WCF service contract
  2. Validations on Data contract
  3. WCF web.config
  4. Handler in client for Fault exception of type ValidationFault

Prerequisites:-

You need to have Enterprise Library 6 validation installed in your solution. This is easy since it has been added to Nuget. Just right click on your solution, click Manage Nuget package and search for "enterpriselibrary wcf". This search is specifically for validation block available for WCF integration. Remember we are not installing the entire Enterprise Library here. Once this is successfully installed, all you need is below references in your classes.


using Microsoft.Practices.EnterpriseLibrary.Validation.Validators;
using Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF;

Step 1: Changes in WCF service contract

First you need to decorate your service contract with ValidationBehaviour which will inform the service consumer that there are validation available on this contract. 















Also you might have noticed, there is a FaultContract declared above the operation contract. Yes, this is required in order to provides heads up regarding the type of Fault the method can return. 

Step 2: Validations on Data contract

In this step, we add our required validations on the data members we need. Enterprise Library Validation block provides a long list of validations you can put on your data members. Please see the full list of validation available.

In my example, I have just used StringLengthValidator & RangeValidators for restricting the length of data which is being passed to my operation contracts. 


And that's it your validation added. Pretty cool right. If you ever have used System.ComponentModel.DataAnnotations, this is almost similar to it. Another benefit of this is if you have front end validations using DataAnnotations then you can easily copy paste them onto your data contract with minor changes.

Also, while declaring validations on your data members, there is an option to define ruleset on them which actually group certain validations together. I will discuss later in this blog the importance of applying ruleset on validations. 

Step 3: WCF web.config

There is a small bit of configuration required in WCF web.config in order to make this working. 

The first step is to specify the Validation block as a behavior extension. Add below in your web.config under extension.

<extensions>
   <behaviorExtensions>
        <add name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF.ValidationElement, Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF" />
   </behaviorExtensions>
</extensions>

Secondly, you need to define endpoint behaviour in your behaviours section which will call this extended behaviour to be applied on your service.


<behaviors>
  <endpointBehaviors>
     <behavior name="ValidationBehavior">
         <validation enabled="true" ruleset="customRuleset" />
      </behavior>
  </endpointBehaviors>
</behaviors>

The ruleset section which is highlighted above enables a specific validation to be executed in all of your validations. Remember I mentioned before while declaring validations on data members you can also group them using ruleset. Well, here that ruleset comes into picture. You can actually force the validation of only a specific ruleset on one endpoint which gives you the freedom of defining different validations for different callers using the same class. 

If you have services block declared already for your service, then you can add this behaviour on it else if you have only one single service defined that there is no need as I never added that block.

Step 4: Handler in client for Fault exception of type ValidationFault

Well at this point, you have configured your WCF to validate the data contract being passed through. And when an invalid data contract is received, your WCF is going fire fault exception and all you need is to catch it properly in order to get the list of all the items which are not as expected by the service.














Here you might have to reinstall the Enterprise Library in your project via Nuget to get that ValidationFault.

Above, all I did is called my service with invalid data and catching the FaultException of the type ValidationFault seperately. It is absolutely necessary to handle this error seperately or all you will get with a normal exception handling is the internal server error from server which isn't going to help you.

And here you go, implemented data contract validation using Enterprise Library. You might be thinking that this is not such a big task for which I will probably get into Enterprise Library but this is a very small example I took what Enterprise Library can do. As soon as your requirements increases, so as your custom code. And having an standard approach always helps in keeping consistency across different things you implement because you would rather not prefer to copy you custom code projects after projects.

Feel free to write anything I would have missed or any questions. If you wish to read more about Enterprise Library, I would recommend official documentation available here.