This is more or less a note-to-self because every time I need to write a custom behavior I have to lookup the way to do it. This post should assist me in the future.
A custom behavior is often used to add functionality to the service that basically is not part of the functionality of the service itself like parameter validation. If you put the validation behavior into a separate assembly you can adjust the validation without affecting (and having to re-test) the service. Most of the time writing a custom behavior is not that difficult, it is the configuration that causes trouble. One little mistake and the service refuses to start.
I’m not going to start with explaining what custom behaviors are, because that is described in this excellent MSDN magazine article from 2007 that still applies to WCF 4. If you’re not familiar with this article, I would strongly advise you to read it.
In my sample project I created a sample WCF service on which I want to apply a custom input validation behavior that validates the input based on a regular expression. This regular expression should be adjustable in the web.config of the service.
Behaviors can be applied using attributes in code or via the web.config. Depending on your requirements you need to implement some interfaces. Because I want my behavior to be configurable, I need to implement these interfaces:
- this determines the scope of the behavior. Options are IServiceBehavior, IContractBehavior and IOperationBehavior
- this determines where the behavior intercepts the call.
- this allows a custom configuration element in the web.config
How the IEndpoint behavior and IParameterInspector work or have to be implemented can be found in many blog posts so it will be briefly discussed here. I would like to focus on the way to get configuration from the web.config.
To get information from the web.config into your application or service, there are two options:
- AppSettings section
- Attribute field on the behavior configuration
Because the setting is behavior specific, I’m in favor of the second option. In this way it is clear that the setting has something to do with the behavior. In the end this would result in such a configuration record.
This is implemented using the code of the class overriding BehaviorExtensionElement. In this class you define the attributes that will be part of the configuration.
Here I declared a ‘ConfigurationProperty’ with the name you find in the web.config and I specified that this setting is a string value and is required. If necessary it is also possible to add the ‘default’ element to the ‘ConfigurationProperty’ attribute to set a default value.
Next this value must be stored in the behavior somewhere, to be used later on in the parameter inspector. Remember that the configuration is read during launch of the WCF service, even without having received one client call!
The value is stored the IEndpoint behavior implementation and then passed to the ParameterInspector. In the picture above this is done in the ‘CreateBehavior’ method. The code below shows the Behavior where also the check is done if the configuration setting is actually there.
If no configuration setting is found, running this service would throw an error on start because the attribute is marked as ‘required’. If the value is empty, then the custom exception is thrown:
Also in the IEndpointBehavior picture you can see that the behavior is only a service side (ApplyDispatchBehavior) behavior and is not applied to the client side (ApplyClientBehavior). These methods are used to inject the behavior in the stack.
Finally we end up in the parameter inspector, where the configuration setting actually is used. The configuration value is passed via the constructor and stored there in a private variable.
With all elements in place it is time to finish the configuration. The section below is located in the ‘system.serviceModel’ section.
Important things to remember:
- The name of the extension = name of the behavior! So the ‘InputValidator’ extension is added, and that is the tag name of the behavior.
- The behavior tag is sometimes not recognized by the Visual Studio editor. It is complaining that the behavior has an invalid (=InputValidator) child element and that only some elements are allowed. Ignore this message!
- Make sure the assembly type of the extension overrides ‘BehaviorExtensionElement’.
- If you normally use the SvcConfigEditor tool to edit the web.config regarding WCF configuration, then you might run into issues. The tool at first cannot find the behavior and once you point it to it the tool refuses to accept it. Or at least that is what I experience.
Finally it is time to test the behavior. In the sample project there is a ‘Host’ project. Build the solution and run ‘Host.exe’ as administrator.
Next there is a ‘TestAppSampleService’ which will call the service with a valid and an invalid value. You can step through the client to find out what happens. Also the output is written to the console, which can be picked up by DebugView. This results in these test results:
The sample project can be found here.