WCF Message validation (1) – WCF samples to the rescue
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.