Recently, I needed to validatie messages going into a WCF service. It turned out the WCF samples are a rich source of knowledge and I found a sample which performs XMLSchema-based validation in \TechnologySamples\Extensibility\MessageInspectors.


 


The sample contains a few classes:



  • ClientValidationException.cs


    • Defines exceptions where validation fails clientside

  • SchemaValidationBehavior.cs


    • Defines an implementation of IEndpointBehavior in order to be an extender for defined endpoints

  • SchemaValidationBehaviorExtensionElement.cs


    • Inherits from BehaviorExtensionElement, used for configuration-time binding

  • SchemaValidationMessageInspector.cs


    • Contains the actual validation code, implementing IClientMessageInspector and IDispatchMessageInspector.

  • ValidationFault.cs


    • Defines FaultExceptions used within the code.

The sample uses a property called Schemas within it’s configuration, allowing us to define which schemas should be taken into account when validating.


 


<schemaValidator validateRequest=True validateReply=True>


<schemas>


<add location=messages.xsd /> 


</schemas>


</schemaValidator>


 


That’s great, but as you all probably know, WCF services have the ABC’s: Address, Binding and Contract. What I actually wanted the behavior to do was validate my message against the actual Contract of the endpoint the validator was working on.


In order for this to work, I did two thing:


 


1.       I removed all “Schemas” configuration and arguments from the code.


2.       I modified the SchemaValidationBehavior class to validate the actual contract.


 


The first steps should be self-explanatory, but the second I want to elaborate on. What I actually did was modify the methods ApplyClientBehavior and ApplyDispatchBehavior. The sample took the configured Schemas property to create the actual SchemaValidationMessageInspector:


 


SchemaValidationMessageInspector inspector =


new SchemaValidationMessageInspector(


schemaSet, validateRequest, validateReply, false);


 


I wanted to dynamically use the endpoint contract:


 


WsdlExporter exporter = new WsdlExporter();


exporter.ExportContract(endpoint.Contract);


 


SchemaValidationMessageInspector inspector =


new SchemaValidationMessageInspector(


exporter.GeneratedXmlSchemas,


validateRequest, validateReply, false);


 


After modifying both methods to perform this kind of setup, it was easy to configure validation based on the endpoint contract (some elements abbreviated for clarity):


 


<system.serviceModel>


<services>


<service name=SomeService>


<endpoint


address=SomeAddress


binding=wsHttpBinding


contract= ISomeService


behaviorConfiguration=SomeServiceEndpointBehavior />


</service>


</services>


 


<behaviors>


<endpointBehaviors>


<behavior name=SomeServiceEndpointBehavior>


<SchemaValidator


validateRequest=True


validateReply=True” />


</behavior>


</endpointBehaviors>


</behaviors>


 


<extensions>


<behaviorExtensions>


<add


name=SchemaValidator


type=SchemaValidationBehaviorExtensionElement, …/>


</behaviorExtensions>


</extensions>


</system.serviceModel>


 


That’s it, now we have a service endpoint validated based on it’s WSDL contract.


 


The sample code is attached for your enjoyment.