WCF provides the developer with the means of extending the service model through the use of behaviors. The behaviours get defined by four interfaces types. IServiceBehavior, IEndpointBehavior, IContractBehavior and IOperationBehavior.
All of these interfaces follow the same template which allows the developer to inject, alter or validate values before dispatching a call. The order in which the methods are called is Validate, ApplyDispatchBehavior and then AddBindingParameters.
- Validate
In this method developers can validate their own custom conditions to whether a dispatch should be allowed. If the custom condition fails a fault exception should be raised here. - ApplyDispatchBehavior
Once validation have been passed the dispatch behavior method is executed. It is probably the most used method. Often the other two method implementations are left blank. The developer can audit, inject or change the values being dispatched at this level. - AddBindingParameters
This method is very seldom used. It gives an opportunity to add parameters to the BindingParameterCollection at run time and is executed once per endpoint in the case of the IServiceBehavior.
Each one of these interfaces intercept the call stack of the incoming and outgoing calls at a different levels within the service or proxy. Behaviours are perfect for using in areas where you have cross cutting concerns like security as an example.
Behaviours are commonly used to do the following; Audit Tracing, Validation, Error Logging, Security verification and Passing of additional data on the headers when a call is dispatched. The behaviours can either be defined at run time or through the service model section in the configuration files.
The Microsoft Validation Block for WCF is a good example of a endpoint behavior. It allows one to define validation rules at contract design time per data member in a data contract and per argument within a service operation which it the enforces at run time.
In this snippet I show an example of the Microsoft Validation Block The validation rules are defined on the service and data contracts and enforced at run time without the developer having to do any additional coding to validate the incoming values.
[ValidationBehavior]
public interface IUserManagement
{
[OperationContract]
[FaultContract(typeof(ValidationFault))]
bool ChangePassword(
[RangeValidator(0, RangeBoundaryType.Exclusive, Int32.MaxValue, RangeBoundaryType.Inclusive, MessageTemplate = “Invalid user Id. ‘userId’ must be greater than zero.”)]
int userId,
[NotNullValidator(MessageTemplate = “Invalid password. ‘password’ may not be null.”)]
[StringLengthValidator(8, RangeBoundaryType.Inclusive, 16, RangeBoundaryType.Inclusive, MessageTemplate = “Invalid password. ‘password’ must be between 8 and 16 characters long.”)]
[RegexValidator(@”([a-zA-Z0-9#@$?_!]){8,16}”, MessageTemplate = “Invalid password. ‘password’ must be between 8 to 16 characters long and may only contain letters, numbers or the following characters: #, @, $, ?, _ or !.”)]
string password,
bool reset);
}