Programmatically Intercepting WCF Messages

Suppose you are testing a WCF (Windows Communication Foundation) service. In some situations you may want to view the low level traffic between a WCF client and the service. The easiest way to do this in general is to use a network analyzer such as netmon and capture the traffic as the client sends a request and receives a response. However in some test automation situations you may want to programmatically capture WCF traffic. There are several good blog posts on this topic but I couldn’t find a complete end-to-end example so I experimented and came up with an example of how to do this.
 
First, let’s assume we have a WCF service name MathService running in either a Console host, or in a Windows Service host, or in an IIS host:
 
[ServiceContract]
public interface IMathService
{
  [OperationContract]
  double Sum(double x, double y);
}
public class MathService : IMathService
{
  public double Sum(double x, double y)
  {
    double answer = x + y;
    return answer;
  }
}
 
To programmatically capture WCF traffic you can first create a Console Application client like so:
 
EndpointAddress epAddress = new
  EndpointAddress("
http://machine:8000/MyWCFMathService/Service/MathService");
MathServiceClient sc = new MathServiceClient(new WSHttpBinding(), epAddress);
// wire up traffic interceptor here in a moment
Console.Write("\nEnter a number: ");
double x = double.Parse(Console.ReadLine());
Console.Write("Enter another: ");
double y = double.Parse(Console.ReadLine());
Console.WriteLine("\nSending " + x + " and " + y + " to Sum in WCF Math Service");
 double ans = sc.Sum(x, y);
Console.WriteLine("\nThe response was: " + ans);
 
Next you can add two classes to the client like so:
 
class MyClientMessageInspector : IClientMessageInspector
{
  public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
  {
    Console.WriteLine("\n\n" + reply.ToString());
  }
  public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
  {
    Console.WriteLine("\n\n" + request.ToString());
    return null;
  }
}
class MyEndpointBehavior : IEndpointBehavior
{
  public void AddBindingParameters(ServiceEndpoint serviceEndpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    { }
  public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, System.ServiceModel.Dispatcher.ClientRuntime behavior)
  {
    behavior.MessageInspectors.Add(new MyClientMessageInspector());
  }
  public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
  { }
  public void Validate(ServiceEndpoint serviceEndpoint)
  { }
}
And then you can wire up the two classes in the client like so:
 
sc.Endpoint.Behaviors.Add(new MyEndpointBehavior());
 
When you execute the Console Application client program, WCF traffic will be echoed to the shell as demonstrated in the partial screenshot below.
 
Advertisements
This entry was posted in Software Test Automation. Bookmark the permalink.