Locations

Blog Stats

Archive for the ‘Debugging’ Category

This post takes a brief look at the options for capturing localhost HTTP traffic in the superb Fiddler2 tool but in particular demonstrates how this can be achieved using the less-renowned ipv4.fiddler keyword in a Silverlight 2 polling duplex debugging session.

HTTP traffic sent to or originating from http://localhost or http://127.0.0.1 by Internet Explorer and the .NET Framework is not captured in Fiddler2 by default because the requests and responses do not pass through the WinInet proxy that it registers. A few simple workarounds do exist to commonly facilitate the capture of this traffic (without customizing Fiddler’s rules) however:

Using 127.0.0.1 with a dot suffix

Using the Machine Name

Using ipv4.fiddler

The rest of this post shows the results of using each of these methods in an attempt to achieve a complete trace of all HTTP traffic being sent and received between my sample Silverlight 2 Beta 2 polling duplex client and server application, the results were quite interesting. The sample application consists of three projects:

The Silverlight 2 Beta 2 client polling duplex application

The Web Application hosting the Silverlight client

The WCF polling duplex service hosted in a Console Application

The server manually handles the Silverlight client access policy requirements and messages are sent in both directions by both parties. Capturing all the traffic between the client and server in Fiddler2 requires the base http://localhost url to be manipulated at design time according to the appropriate workaround in each of the three projects. Let’s take a look at the process using each workaround in turn and the ensuing results:

1. Using 127.0.0.1 with a dot suffix

I first read about this technique here and it does work in a number of more common scenarios, let’s see how it fares in this scenario:

A. Silverlight Client

Firstly the manipulation of the default http://localhost url used to connect to the server duplex service from the Silverlight 2 client project:

// From this
EndpointAddress endPoint = new EndpointAddress("http://localhost:10201/StockService");
// To this - Note the period after localhost
EndpointAddress endPoint = new EndpointAddress(http://127.0.0.1.:10201/StockService);

B. Hosting Web Application

Secondly the same change to the Start URL for the web application that hosts the Silverlight 2 client:

C. WCF Service Console Application

Lastly a change to the base address of the WCF polling duplex service in the server’s configuration file:

D. Results in Fiddler

The screenshot above shows the results of our efforts using this workaround. The session gets as far as the GET request for the built-in clientaccesspolicy.xml file. Due to our manually added suffix a HTTP 400 Bad Request – Invalid Hostname response is returned. This HTTP response is eventually translated into the following exception in the Silverlight client:

2. Using the Machine Name

This is a technique listed in the relevant help section on the Fiddler2 website, lets see what results this workaround yields:

A. Silverlight Client

Again we start with the manipulation of the default http://localhost url used to connect to the server duplex service from the Silverlight 2 client project:

// From this
EndpointAddress endPoint = new EndpointAddress("http://localhost:10201/StockService");
// To this (i.e. Environment.MachineName)
EndpointAddress endPoint = new EndpointAddress(http://vgnar21s:10201/StockService);

B. Hosting Web Application

Again, the same change to the Start URL for the web application that hosts the Silverlight 2 client:

C. WCF Service Console Application

Lastly a change to the base address of the WCF polling duplex service in the server’s configuration file:

D. Results in Fiddler

The screenshot above shows the results of our efforts using this workaround. The session does not get past the request for the aspx page that hosts the Silverlight application and a HTTP 502 Connection Failed response is returned. This HTTP response message eventually appears as the following error in Internet Explorer:

3. Use ipv4.fiddler keyword

At this stage the two previous workarounds have both proven unsuccessful, let’s try the same process this time with another technique listed in the relevant help section on the Fiddler2 website – use of the ipv4.fiddler keyword. The ipv4.fiddler keyword requires Fiddler v2.1.8 or later to be running, I should also mention the ipv6.fiddler keyword (not covered in this post) for IPV6 debugging.

A. Silverlight Client

Firstly the manipulation of the default http://localhost url used to connect to the server duplex service in the Silverlight 2 client project:

// From this
EndpointAddress endPoint = new EndpointAddress("http://localhost:10201/StockService");
// To this (Fiddler keyword)
EndpointAddress endPoint = new EndpointAddress(http://ipv4.fiddler:10201/StockService);

B. Hosting Web Application

Secondly the same change to the Start URL for the web application that hosts the Silverlight 2 client:

C. WCF Service Console Application

Lastly a change to the base address of the WCF polling duplex service in the server’s configuration file:

D. Results in Fiddler

Success – this workaround accomplishes exactly what we set out to achieve, the screenshot above shows the capture of all HTTP traffic going between the client and server. It shows everything from the initial request for the hosting aspx page, downloading the .xap file, the request and custom self-hosted response for the clientaccesspolicy.xml file and finally the actual polling duplex activity on the wire. Note the content of the User-defined column, this is as a result of turning on ‘Show Time-to-Last-Byte’ and ‘Show Response Timestamp’ under the Rules > Performance menu in Fiddler2.

For a deep-dive into exactly what these polling duplex requests and responses contain, please see the ‘Anatomy of a Bi-Directional Message Exchange’ heading in Part 1 – Architecture of my series of posts on polling duplex in Silverlight 2.

It can be difficult to debug exceptions in a Silverlight applications in Visual Studio 2008 in certain scenarios at present. If you’re having trouble tracking down where an exception is occurring in your Silverlight application and find it awkward dealing with the yellow exclamation :

Don’t forget you’ve got the Application events to help you out. An event handler for the UnhandledException event of the Application class is wired up by default for new Silverlight Applications. If you set a breakpoint here you can get a call stack back to where the problem is occurring :

I ran into a minor problem recently where Visual Studio 2008 was closing unexpectedly with the message that it had encountered a user-defined breakpoint.

I believe the problem occurred when the Silverlight 2.0 XAML parser encountered some XAML for a custom control and hit a System.Diagnostics.Debugger.Break() statement in the handler for a dependency property’s PropertyChangedCallback. This dependency property was part of a custom control which I had referenced and declared in Page.xaml in my main Silverlight Application project.

The steps to recreate the problem include having Page.xaml open in Split View or Designer view (XAML view does cause the error but only intermittently it seems) and finally performing a build; whereupon you receive the message :

The next step is either that Visual Studio restarts itself only to encounter the same error when it starts again, this can happen several times until you get the message…

…or, that you get the following error :

In which case after you click Close Program, Visual Studio’s UI is grayed out while an error reporting .exe does it’s work, sometimes necessitating user action to kill the process using task manager.

Note that the reason for posting this issue and previous issues on my blog is purely to provide feedback, as Silverlight 2.0 is still in Beta 1 problems are to be expected.

Currently, the debugger does not suspend execution at present even if you do successfully start debugging a Silverlight solution containing this statement. Surrounding the statement with a conditional directive also does not solve the problem so to avoid this issue simply avoid using the System.Diagnostics.Debugger.Break() statement, and use breakpoints instead for now in Silverlight 2.0 projects.

I ran into an issue today when debugging a Silverlight project in Visual Studio 2008. I had previously been able to hit breakpoints in the project and hadn’t changed any settings, but for some reason it had stopped working.

I knew there was a checkbox in the Property Pages of the hosting web site under Start Options that has to be enabled for breakpoints to be hit when debugging Silverlight Applications, this checkbox is checked by default when you create a new Silverlight Application as shown below:

Turns out when I checked the properties of my hosting web site project, this checkbox was unchecked – the cause of my breakpoints not being hit, re-enabling solves the problem :

But as I said I had previously been able to hit breakpoints in the project and hadn’t changed any settings. The only thing I had done after closing Visual Studio 2008 last night was to move the solution into another directory under the default Projects folder.

With a bit of investigating it turns out that when I moved the solution to a new folder and then opened the copy in Visual Studio, the Silverlight Debuggers checkbox under Start Options had been cleared.

To re-create firstly create a new Silverlight Application project with the default ‘Web Site’ host and confirm the checkbox is checked under Start Options in the web site’s Property Pages. Then close Visual Studio and move or copy the whole solution, to the same folder even. If you made a copy and open the original project the checkbox will still be checked and your breakpoints will work, if you open the copy or the moved solution then the checkbox will have been cleared.

Interestingly the checked value of the Silverlight Debuggers checkbox is not kept for copies with a normal ASP.NET web site when Silverlight is not involved either. It would be good to find out if this is by design or if I’ve missed something?