Custom Message Handling with WCF (Part 1 of 2)

Windows Communication Foundation (WCF) is a great framework for creating service-oriented applications. It provides APIs for creating, hosting and consuming services, through text-based protocols like HTTP or binary protocols like TCP or even named pipes. Most of the time, you would conveniently rely on WCF to serialize and deserialize requests and responses on the fly, letting you focus on the business logic. However, sometimes it is necessary to take full control of the messages transferred to another endpoint, or to interpret response messages without WCF interfering with its deserialization functionality.

To take control of the messages, you need to interacts with WCF’s Message class. By default, when you add a service reference in Visual Studio, a set of classes are generated to represent the elements of the messages recognized by the service. To interact with the Message class, you need to write your own WCF client, rather than relying on Visual Studio service references. This might sound intimidating, but is actually quite easy.

With the .NET SDK comes a tool called ServiceModel Metadata Utility Tool (Svcutil.exe). This command line tool generates WCF clients based on WSDL metadata. As a matter of fact, Visual Studio relies on Svcutil to generate its service references. When creating WCF clients without the support of Visual Studio service references, I find it useful to base my code on the types generated by Svcutil.

In order to interact with the Message class, the service interfaces generated by Svcutil require some slight modifications. MSDN provides an article, “Using the Message Class“, which contains information and examples on how to modify the service interface to enable interaction with the Message class. In short, for each operation you require custom handling, replace the parameters (if any) with a single Message parameter or a single MessageContract-attributed type. Further, if it is a non-void operation, the return type must be Message.

Once the interface is modified to fit your requirements, you are ready to create your custom WCF client. This is, in fact, very easy. Creating a custom WCF client is simply a matter of inheriting ClientBase<TChannel> and delegate all method calls to base.Channel.

Consider this simple interface:

[ServiceContract(
    Namespace = "https://lookingsharp.wordpress.com/demo/",
    ConfigurationName = "IMyService")]
public interface IMyService
{
    [OperationContract(
        Action = "https://lookingsharp.wordpress.com/demo/IMyService/GetData",
        ReplyAction = "https://lookingsharp.wordpress.com/demo/IMyService/GetDataResponse")]
    Message GetData(Message request);
}

The code for the corresponding WCF client would the be:

public class MyServiceClient : ClientBase<IMyService>, IMyService
{
    public Message GetData(Message request)
    {
        return base.Channel.GetData(request);
    }
}

This client will by default use the configuration called IMyService, generated by Svcutil along with the IMyService interface. Include this generated configuration in you application’s app.config file, and tweak it as you wish.

In part two I show, step by step, how to create a WCF client that does not rely on the default WCF message deserialization, and rather prints the raw XML content of the response message to the console.

Leave a comment