SoapWatch

Introduction

This is yet another of my little play projects. The idea here was more to fool around with some libraries I wanted to get my hands on rather than to provide something useful. I might add stuff to the tool or not ever touch it again. Time will tell ;P

SoapWatch is a debugging proxy that allows to get a good overview of WCF calls being made. You can achieve the same with Fiddler, however since Fiddler aims to debug web traffic you want get a good overview and have to drill into individual requests to get to the raw XML. My first idea was to write a visualizer for Fiddler, however you would still have to select requests before seing which methods are actually invoked.

There are basicly two libraries I wanted to test:

  • FiddlerCore
    FiddlerCore exposes that fiddler proxy engine to allow hosting in your own applications. This is an absolutely great feature. It's really hard to get such an engine right by yourself considering the complexity of the HTTP protocol when used extensively.
  • Nancy
    Nancy is a lightweight web framework that allows to easily implement self hosted web servers. It has a lot more capabilities and even allows scenarios like building web sites that are independent of IIS using abstractions.

In addition I used jQuery for the client scripting.

The Main Parts

At the highest level SoapWatch consist of two parts, the proxy that intercepts the SOAP calls and the WPF client that can visualize the data.

FiddlerCore

The proxy uses FiddlerCore. Setting the interception up with the library is damn easy:

FiddlerApplication.Startup(8889, FiddlerCoreStartupFlags.MonitorAllConnections);
FiddlerApplication.BeforeResponse += new SessionStateHandler(FiddlerApplication_BeforeResponse);

8889 is the port to listen on - I decided not to use the standard Fiddler port 8888 to prevent collisions. I attach a handler to the event that is fired after a response arrived. At a later point I might want to attach a handler that gets the beginning of the request. This way I would be able to show pending requests as well and not the whole request/response after the fact.

Nancy

Getting Nancy to work is really easy as well. This is the bare minimum you have to do:

NancyHost host = new NancyHost(new Uri("http://localhost:8890"));

As you might guess Nancy will listen on port 8890. You might ask yourself how to define, where incoming requests are handled. By default Nancy uses a reflection based auto discovery method. It will wire up all classes deriving from NancyModule in the assembly. You might compare the function of such a module to a controller in the MVC world. In contrast to ASP.NET MVC modules in Nancy define routes for themselves.

public class MainModule : NancyModule
{
    public MainModule() : base("/")
    {
        Get["/"] = _ =>
        {
            return View["Default.html"];
        };
    }
}

This module defines that it's base is the root folder (with the base call). It then accecpts HTTP get requests and returns the view "Default.html". As you see it's a really slim version of MVC. Nancy supports view engines, it uses it's own by default but also allows engines like Razor or Spark. You may define route parameters:

Get[@"/(?<file>.*\.png)"] = parameters =>
{
    return Response.AsImage("Views/" + (string)parameters.file);
};

As you see the GET request is a regular expression and you can use matches to define parameters. The Response object offers lots of extension methods (like AsImage in this example) to handle different kinds of content. By default the view engine searches for it's files relative to the application folder.

To get query string parameters you can use the Request object:

bool isTruncated = Request.Query["truncate"].HasValue && Request.Query["truncate"].Value == "true";

Nancy can do much more (e.g. model binding, bootstrapping...). I just used the bare minimum here.

The WPF Client

After setting up the Fiddler interceptor and initializing Nancy, the client opens a form that contains a browser control. I decided to go with a browser control instead of a XAML based UI to make extensibility easier. When adding visualizers you can just code something that emits HTML instead of getting deep into WPF. I did not launch a browser to be able to terminate the whole application with one click instead of having to close the browser and stop the fiddler monitoring.

The browser control is pointed to the Nancy hosted web site http://localhost:8890. It recieves a litte application with jQuery that basicly uses ajax calls to poll for new data.

I found out one thing with WPF and tray icons that nagged me in previous projects. When you close your application the tray icon stays there until you hover over it with your mouse. I found out that callling dispose on the icon when closing down the application remedies the problem.

Enabling Monitoring for WCF Clients

To enable monitoring for WCF clients you must configure WCF to use a proxy at http://localhost:8889. Here is a snippet from web.config that does the job.


<basicHttpBinding>
  <binding name="MyBinding" bypassProxyOnLocal="false" useDefaultWebProxy="false" proxyAddress="http://localhost:8889" />
</basicHttpBinding>

It's important to not use the default proxy. Unfortunately the bypassProxyOnLocal does not work as expected. If you have the service endpoint located on your local machine as well you will not run through the proxy. The easiest way around this is to use the machine name or LAN IP address instead. A nice way to enable/disable debugging with one switch in configuration is to put some code into the channelfactory that reads a setting whether to use the proxy and then sets the proxy and remote address. When newing up a channel factory in WCF you may specify the configuration name of the binding:

var channelFactory = new ChannelFactory<IService1>(
    new BasicHttpBinding ("MyBinding"),
    new EndpointAddress(url));

Now the good news is, that you may alter the binding after creation. Like this you can specify your parameters in web.config/app.config and then apply proxy settings afterwards.

Usage

You can use the start/stop/clear buttons to control capturing and clear the log. The log will cycle at 100 records. Click the tray icon to restore the application when minimized.

Final Words

As said before, this project is just for playing. I did not take a deep look into SOAP specs and did just some XML fiddling to show the data. It might not work for you at all. This project was more about getting some insides on the technologies used, mainly Nancy. I hope you found some valuable information in this article and got animated to play around with the stuff as well. If you have any questions or comments feel free to drop me a note.

SoapWatch-0.1.zip (451,81 kb)

About the author

for comments and suggestions contact:

 

Month List