C++ •  VB6 •  VBA •  .NET  •  Silverlight 2 •  ASP.NET

Universal Trace Monitor for Software Developers and Testers

Using DevTracer with Microsoft® Silverlight™

Silverlight is a fairly new technology from Microsoft. It provides a cross platform plugin for browsers for creating rich internet applications.

Silverlight 2 is currently in beta. Applications can be developed with .NET languages like C# and Visual Basic® .NET. Silverlight has its own version of the .NET framework, which is a small subset of the standard framework to give it a small footprint what download size is concerned. It is called .NET Framework Class Library for Silverlight.

Because the framework is a small subset of the standard framework, many classes are missing. Unfortunately the class TraceListener is missing as well. Therefore it is not possible to use DevTracer the way it is possible with a Windows Forms or ASP.NET application.

The framework for Silverligth still contains a class Debug in namespace System.Diagnostics. But this class is limited; it outputs the trace information to the output window of Visual Studio, and it does not use a TraceListener. It also does not have methods Indent(), Unindent() and Write(), which are part of the Debug class in the full framework class library. And class Trace is missing completely.

Therefore it is not possible to use DevTracer Component with Silverlight. But because DevTracer can be used with ASP.NET, there is still a way to use it.

Normally you will use ASP.NET on the server when you develop a Silverlight application, and the Silverlight plugin is hosted in an ASP.NET page. The  principle is fairly easy: send the trace information to a Web Service build with ASP.NET, and this Web Service then uses DevTracer Component to send it to DevTracer Monitor. The steps to make it work are:

  • Add a Web Service to your ASP.NET application.

    Just add one method to this Web Service: public void WriteLine(string str)

  • Configure the ASP.NET application to use DevTracer.
  • Add a reference to the Web Service to your Silverlight application.
  • Add a class NRTracer to your Silverlight application which encapsulates the Web Service.

    This class is handling the calls to the WebService.

Then you will be able to add tracing to your Silverlight application with code like this:

NRTracer.WriteLine("Hello from Silverligth");

Step by Step

For this step by step guide we use Visual Studio 2008. Silverlight 2 beta must be installed. It can be downloaded at the Silverlight site.

Create a new Silverlight project

Start Visual Studio 2008 and create a new Silverlight project

New Project dialog in Visual Studio 2008 to create the Silverlight project

In the next dialog for adding a web site just take the defaults.

Add Web Site dialog

Add a button

Now the solution will be created with two projects: SilverlightDemoWeb for the ASP.NET application and SilverlightDemo for the Silverlight plugin. Initially the file Page.xaml is displayed, which is basically empty (without any controls yet). Therefore just add a button with an event handler for the click event. The xaml code should look like this:

<UserControl x:Class="SilverlightDemo.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Button x:Name="TestButton" Click="TestButton_Click" Width="100" Height="50" Content="Click
            Me!" />
    </Grid>
</UserContro>>

 

Add a Web Service to SilverlightDemoWeb

To add a Web Service, right click the project SilverlightDemoWeb and select Add New Item ... The Add New Item dialog is shown. Choose WCF Service, change the name to DevTracerService.svc, and close the dialog using the Add button.

Dialog to add a Web Service to project SilverlightDemoWeb

Visual Studio adds the Web Service to the project, and displays file IDevTracerService.cs with the Service Contract. It already has a method DoWork(). Change this method to WriteLine(string str). The file with the Service Contract should look like this now:

[ServiceContract]
public interface IDevTracerService
{
    [OperationContract]
    void WriteLine(string str);
}

 

The using statements have been omitted here. You must also change file DevTracerService.cs. Replace method DoWork() with WriteLine()

public class DevTracerService : IDevTracerService
{
    public void WriteLine(string str)
    {
        System.Diagnostics.Debug.WriteLine(str);
    }
}

 

Here we use the class Debug of the standard .NET framework. Instead of calling Debug.WriteLine(), it is possible to call Trace.WriteLine() alternatively. The difference is: Debug.WriteLine() is only available when building a debug version, Trace.WriteLine() is also available in the release version.

Important:

Behind the scene Visual Studio does quite some work when creating the Web Service. Part of the work it does is writing some configuration information about the Web Service to WEB.CONFIG. Unfortunately with the beta version of Silverlight 2 the Web Service will not work with the information in WEB.CONFIG. You must make a change manually.

Load WEB.CONFIG and scroll to the bottom. There you will find the following lines:

<services>
 <service behaviorConfiguration="DevTracerServiceBehavior" name="DevTracerService">
  <endpoint address="" binding="wsHttpBinding" contract="IDevTracerService">

 

The binding must be changed from wsHttpBinding to basicHttpBinding

<services>
  <service behaviorConfiguration="DevTracerServiceBehavior" name="DevTracerService">
    <endpoint address="" binding="basicHttpBinding" contract="IDevTracerService">

 

Now we have to configure the Web Service to use DevTracer Component. We choose to use the configuration file method and add the following lines to WEB.CONFIG.

<system.diagnostics>
  <trace autoflush="false" indentsize="4">
    <listeners>
      <add name="myListener"
           type="NRSoftware.Tracer.Listener,NRSoftware.Tracer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=867dfab712f16c0b"
           initializeData="localhost:12345" />
      <remove name="Default" />
    </listeners>
  </trace>
</system.diagnostics>

 

In these configuration settings please have a look at initializeData="localhost:12345". 12345 is the port number used, and localhost specifies the ip address used to send trace information to DevTracer Monitor (localhost corresponds to 127.0.0.1). If you want to run DevTracer Monitor on a computer different from the one running the Web Service, you have to adjust this setting.

Now we are finished with project SilverlightDemoWeb. Now we have to prepare the Silverlight plugin.

Add a Service Reference to SilverlightDemo project

To add the service reference, right click project SilverlightDemo in solution explorer and select Add Service Reference ... . The Add Service Reference dialog pops up, with basically all fields empty.  Press the button Discover, and the Web Service we created before will be found. Select IDevTracerService on the left, and change the name to DevTracerService before proceeding with OK.

Add Service Reference dialog in Visual Studio

Now we only need the helper class to encapsulate the call to the Web Service.

Add wrapper class NRTracer

This is quite easy. Right click project SilverlightDemo in solution explorer and select Add → Class... . Enter NRTracer.cs as name. You get an empty class skeleton, which needs to be filled with some life. Here is the completed class:

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace SilverlightDemo
{
    public static class NRTracer
    {
        private static DevTracerService.DevTarcerServiceClient _client = null;

        public static void WriteLine(string str)
        {
            if (_client == null)
                _client = new SilverlightDemo.DevTracerService.DevTarcerServiceClient();
            _client.WriteLineAsync(str);
        }
    }
}
NRTracer.cs Download

 

That's all. Now your Silverlight application is ready to use DevTracer. You just have to call

DevTracer.WriteLine("information ....");

 

and the information will be displayed.

In the first step Create a new Silverlight project we added a button to page.xaml, including a click event handler TestButton_Click. Let's fill this event handler with some code. The event handler can be found in file Page.xaml.cs

private void TestButton_Click(object sender, RoutedEventArgs e)
{
    NRTracer.WriteLine("In Event Handler 'TestButton_Click' : Hello from Silverlight");
}

 

Now let's start DevTracer Monitor (ip address to listen to should be localhost, the port 12345) and the Silverlight application (F5 in Visual Studio). The browser will start, and display an empty page with the button created before. Clicking the button then shows the message from the event handler in DevTracer Monitor.

Running Silverlight test application with DevTracer Monitor

 

Some Remarks about this implemention

The sample code shown here only implements one method in class NRTracer and the Web Service: WriteLine(). Theoretically it would be possible to implement methods like Write(), Indent() and Unindent() as well. We did not do this for a simple reason. With .NET for Silverlight you can call a Web Service only asynchronously (that's why class DevTracer call the method WriteLineAsync(), there is no method WriteLine()).

This has some consequences. Look at the following code snippet:

for (int line=1 ; line <=1000 ; line++)
{    
        NRTracer.WriteLine(string.format("This is line no. {0}.",line));
}

 

Running this code works, but looking closely at the data received by DevTracer Monitor will reveal that sometimes the data do not appear in the order expected.

This is caused by the asynchronous calls to the web service. But because there is no guarantee that the data are received in the same order they were send, methods like Write() or Indent() do not make much sense.

With some effort it is possible to synchronize calls to the Web Service. But it is not recommended.

In case it is required that data arrive in the Monitor in the correct order, we recommend a different approach. For this case enhance class DevTracer to cache trace information, and add a method which flushes the cached information and sends them to the Web Service. The enhancement could look like this:

private static StringBuilder _sb = null;

public void WriteLineToCache(string str)
{
  if (_sb == null)
     sb = new StringBuilder();
  sb.AppendLine(str);   
}    

public void Flush()
{
  if (_sb != null)
    {
       WriteLine(_sb.ToString());
       _sb = null;
    }
}
    
    

 

The sample with 1000 lines can then be rewritten:

for (int line=1 ; line < 1000 ; line++)
{
  NRTracer.WriteLineToCache( string.format("This is line no. {0}.",line));
}
NRTracer.Flush();