Simple WCF Service Behavior: Inspect Messages Through Debug Output

As I demo various web service technologies to customers, inevitably someone is really interested in the tools that I am using to trace and inspect messages. My favorite tool for that purpose is tcpTrace, although there are plenty of other trace utilities for web services.

Here's a simple and crude yet incredibly useful utility for dumping the entire message for a WCF service out to the Debug Output window.

First, implement a DispatchMessageInspector, which inspects the messages on the service.

using System;

using System.Xml;

using System.IO;

using System.ServiceModel;

using System.ServiceModel.Channels;

using System.ServiceModel.Dispatcher;

 

namespace WCFExtensions

{

public class MyMessageInspector : IDispatchMessageInspector

{

public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)

{

System.Diagnostics.Debug.WriteLine(request.ToString());

return null;

}

 

public void BeforeSendReply(ref Message reply, object correlationState)

{

System.Diagnostics.Debug.WriteLine(reply.ToString());

}

}

}

 

Next, create an attribute to bind the inspector to the service (yeah, this would be better done in config, but I was anxious to post this… will update with a config-based approach later).

using System;

using System.ServiceModel;

using System.Collections.ObjectModel;

using System.ServiceModel.Channels;

using System.ServiceModel.Description;

using System.ServiceModel.Dispatcher;

 

namespace WCFExtensions

{

[AttributeUsage(AttributeTargets.Class)]

public class MyMessageInspectionBehaviorAttribute : Attribute, IServiceBehavior

{

#region IServiceBehavior Members

 

public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)

{

//noop

}

 

public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

{

foreach (ChannelDispatcher channelDispatch in serviceHostBase.ChannelDispatchers )

{

foreach (EndpointDispatcher endpointDispatch in channelDispatch.Endpoints)

{

endpointDispatch.DispatchRuntime.MessageInspectors.Add(new MyMessageInspector());

}

}

}

 

public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)

{

//noop

}

#endregion

}

}

 

Finally, use the behavior from any service that you have implemented. I highlighted the use of our custom attribute for clarity.

 

using System;

using System.ServiceModel;

 

[ServiceContract()]

public interface Iservice2

{

[OperationContract]

string MyOperation1(string myValue);

}

 

[WCFExtensions.MyMessageInspectionBehavior]

public class service2 : Iservice2

{

public string MyOperation1(string myValue)

{

return "Hello: " + myValue;

}

}

The result is not all that impressive unless you have grown accustomed to the pain of altering the proxy URL in Visual Studio 2005 in your client proxy and firing up tcpTrace. That is, until you realize that you forgot to restart tcpTrace so that something is listening on the port that you specified.

Screen shot of debug output in Visual Studio 2005 containing the SOAP for our simple service call

I'd love to see this type of feature show up in the next Visual Studio release, making it simple to inspect messages on the fly in debug mode.

Some disclosure here. You need to have a debugger attached to the service process to be able to see the output in debug. If you are running your service with an ASP.NET host (using .svc file) under the ASP.NET Development Server (the Cassini web server that comes with Visual Studio 2005), you need to attach your debugger to the WebDev.WebServer.EXE process to get the debug goodness to show up. If you are debugging a self-hosted service, you need to attach to your ServiceHost implementation.