<?xml version="1.0" encoding="UTF-8"?><!--RSS generated by Windows SharePoint Services V3 RSS Generator on 13/03/2010 14:47:16--><?xml-stylesheet type="text/xsl" href="/blog/_layouts/RssXslt.aspx?List=98d5c6c7-5808-4bc4-a33a-5cd0f6350ed4" version="1.0"?><rss version="2.0"><channel><title>Blog</title><link>http://www.dotnetsolutions.co.uk/blog</link><description>RSS feed for the Posts list.</description><lastBuildDate>Sat, 13 Mar 2010 14:47:15 GMT</lastBuildDate><generator>SharePoint CKS:EBE</generator><ttl>60</ttl><image><title>Blog</title><url>http://www.dotnetsolutions.co.uk/blog/_layouts/images/homepage.gif</url><link>http://www.dotnetsolutions.co.uk/blog</link></image><item><title>MIX 10 Session Gadget</title><link>http://www.dotnetsolutions.co.uk/blog/archive/2010/03/12/mix-10-session-gadget/</link><guid isPermaLink="False">/blog/archive/2010/03/12/mix-10-session-gadget/</guid><description><![CDATA[<div class="ExternalClassEAAB0942D49344F9BF6B22AAC5ADB243">
<p align="left">Unfortunately Dot Net Solutions will not be at MIX this year, at least not in body even if we will be in spirit. Our absence only serves to drive our commitment to contribute to the event and its delegates. </p>
<p align="left">Following on from the highly successful PDC session gadget that we released for PDC last year we are pleased to announce the availability of our MIX 10 Session Gadget!</p>
<p align="left"><img width="279" height="506" style="border-right-width:0px;margin:0px auto 20px;display:block;float:none;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="gadget" border="0" alt="gadget" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/MIX10SessionGadget_CFA7/gadget_3.jpg">Install this on your Windows 7 (or Windows Vista) laptop and you can view session information for each day, search for sessions by keyword and stay up-to-date with constantly updating session schedules. The gadget also works offline. Enjoy MIX!</p>
<p><a href="http://mix10gadget.dotnetsolutions.co.uk/mix10.gadget" title="Download MIX 10 Gadget" rel="nofollow"><img width="150" height="50" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px" title="Download MIX 10 Gadget" border="0" alt="Download MIX 10 Gadget" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/MIX10SessionGadget_CFA7/download-now_3.gif"></a></p>

</div>]]></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">DOTNETSOL\Derek</dc:creator><pubDate>Fri, 12 Mar 2010 14:44:00 GMT</pubDate><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Community/">Community</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Windows 7/">Windows 7</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/MIX/">MIX</category></item><item><title>Connecting to SQL Azure without changing your firewall</title><link>http://www.dotnetsolutions.co.uk/blog/archive/2010/03/03/connecting-to-sql-azure-without-changing-your-firewall/</link><guid isPermaLink="False">/blog/archive/2010/03/03/connecting-to-sql-azure-without-changing-your-firewall/</guid><description><![CDATA[<div class="ExternalClass7FD5FBA5A521464597C5A8B2E00E8C8D">
<p>I’ve been speaking about Azure at a number of events recently. One of the biggest challenges that I have had each time is due to local firewall restrictions. Firewalls will block port 1433/1434 outbound and this a major hassle to get changed, especially for a 20 minute demo. These ports are generally restricted due to the SQL slammer and SQL snake viruses (<a href="http://www.grc.com/port_1434.htm" title="http://www.grc.com/port_1434.htm" target="_blank">http://www.grc.com/port_1434.htm</a>) from a few years ago.</p>
<p>SQL Azure uses port 1433 for communication, for instance when connecting from management studio to SQL Azure you get a dialog such as this:</p>
<p><a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/ConnectingtoSQLAzurewithoutchangingyourf_E3B6/image_18.png"><img width="249" height="291" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/ConnectingtoSQLAzurewithoutchangingyourf_E3B6/image_thumb_7.png"></a> </p>
<p> </p>
<p>With the port blocked, the connection attempt simply times out. One simple solution is to create a VPN connection to another network that has firewall rules configured to allow access. While this works, it does add latency, not only, to the SQL Azure communication but to all internet communication. However, there are other approaches.</p>
<h2>Port Bridge</h2>
<p>If you haven’t read Clemens Vasters’ post on Port Bridge, then I can highly recommend it: <a href="http://vasters.com/clemensv/CommentView.aspx?guid=3e35d8bd-b755-453f-8c63-1a57c570eb4c" target="_blank">http://vasters.com/clemensv/CommentView.aspx?guid=3e35d8bd-b755-453f-8c63-1a57c570eb4c</a>. Port Bridge is a sample application that provides point to point tunnelling between a client and server. It does this by wrapping the protocol and port used for the communication within a SOAP message. This message can then be relayed using the Windows Azure AppFabric Service Bus and unwrapped at the destination.</p>
<p>The Service Bus provides the ability to connect on-premise applications together or to connect an on-premise application to an application in the cloud. The Service Bus addresses the challenges presented by firewalls, NATs and dynamic IP, so your endpoints do not have to be published directly to the Internet just have Internet access.</p>
<p><img width="489" height="176" title="Port Bridge" border="0" alt="Port Bridge" src="http://vasters.com/clemensv/content/binary/WindowsLiveWriter/865a80e15ca0_D9A4/image_thumb.png">  </p>
<p>The diagram is from Clemens’ original port and describes exactly the situation and solution to my current issue, where SQL Server is actually SQL Azure.</p>
<h2>Using Port Bridge</h2>
<p>Back to the original challenge: to demo SQL Azure by connecting from SQL Server Management Studio and an application on my local machine.</p>
<p>My office network is set up so that I have access to SQL Azure, so my first approach was to run the Port Bridge Service from my PC back in the office. With the Port Bridge Agent running on my demo laptop listening on port 1433. To set up the Port Bridge Agent to proxy message to SQL Azure, configure the local TCP port and remote TCP port to 1433 and set the target host as the SQL Azure database server name.</p>
<pre class="csharpcode">  <span class="kwrd">&lt;</span><span class="html">portBridgeAgent</span> <span class="attr">serviceBusNamespace</span><span class="kwrd">=&quot;myservice&quot;</span> 
<span class="attr">serviceBusIssuerName</span><span class="kwrd">=&quot;owner&quot;</span> <span class="attr">serviceBusIssuerSecret</span><span class="kwrd">=&quot;x1x1x1x1x1x1xx1x1x1=&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">portMappings</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">port</span> <span class="attr">localTcpPort</span><span class="kwrd">=&quot;1433&quot;</span> <span class="attr">targetHost</span><span class="kwrd">=&quot;x2wqed1zpk.database.windows.net&quot;</span> 
<span class="attr">remoteTcpPort</span><span class="kwrd">=&quot;1433&quot;</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">firewallRules</span><span class="kwrd">&gt;</span>
          <span class="kwrd">&lt;</span><span class="html">rule</span> <span class="attr">source</span><span class="kwrd">=&quot;255.255.255.255&quot;</span> <span class="kwrd">/&gt;</span> <span class="rem">&lt;!-- My local IP address --&gt;</span>
        <span class="kwrd">&lt;/</span><span class="html">firewallRules</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">port</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">portMappings</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">portBridgeAgent</span><span class="kwrd">&gt;</span></pre>
<style>
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode, .ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode pre
{margin:0em;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .rem
{color:#008000;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .str
{color:#006080;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .op
{color:#0000c0;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .html
{color:#800000;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode, .ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode pre
{margin:0em;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .rem
{color:#008000;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .str
{color:#006080;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .op
{color:#0000c0;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .html
{color:#800000;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .lnum
{color:#606060;}
</style>
<p>In order for the Port Bridge Agent to listen on port 1433, I need to ensure that anything else listening on port 1433 is stopped (such as the SQL Server service). To connect to the SQL Azure database I need to specify “localhost” as the server name when connecting and provide the login/password as usual. This traffic is intercepted by the Port Bridge Agent and routed via the Service Bus to the Port Bridge Service and then to the target host, “x2wqed1zpk.database.windows.net”, the SQL Azure database.</p>
<p><a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/ConnectingtoSQLAzurewithoutchangingyourf_E3B6/image_10.png"><img width="465" height="318" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="Port Bridge to SQL Azure" border="0" alt="Port Bridge to SQL Azure" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/ConnectingtoSQLAzurewithoutchangingyourf_E3B6/image_thumb_3.png"></a> </p>
<h2>Using Port Bridge in Windows Azure</h2>
<p> </p>
<p> </p>
<p>While I can conveniently run the Port Bridge Service on my PC as a windows service (or a console application), it would be useful to have a little more control over when this service is running and a little more resilience. These are exactly the features that a Windows Azure worker role would provide. I would be able to stop and start the Port Bridge Service remotely and would not need any access to my PC or my office network.</p>
<p>Starting from the Port Bridge sample application, to create a Port Bridge Service worker role requires a few steps. </p>
<ul>
    <li>Add a new Cloud project and a worker role to the sample solution. </li>
    <li>To the worker role, add references to the “Microsoft.Samples.ServiceBus.Connections” and “PortBridge” projects in the solution. </li>
    <li>Also add a reference to Microsoft.ServiceBus.dll, ensuring that you set the “Copy Local” property to true. </li>
    <li>With a little refactoring of the PortBridge Program Main, this method can be used from the worker role (there is certainly scope to provide a much neater solution). </li>
    <li>Finally, update the app.config with the service settings: </li>
</ul>
<pre class="csharpcode">  <span class="kwrd">&lt;</span><span class="html">portBridge</span> <span class="attr">serviceBusNamespace</span><span class="kwrd">=&quot;myservice&quot;</span> <span class="attr">serviceBusIssuerName</span><span class="kwrd">=&quot;owner&quot;</span> 
<span class="attr">serviceBusIssuerSecret</span><span class="kwrd">=&quot;x1x1x1x1x1x1xx1x1x1=&quot;</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">hostMappings</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">targetHost</span><span class="kwrd">=&quot;x2wqed1zpk.database.windows.net&quot;</span> <span class="attr">allowedPorts</span><span class="kwrd">=&quot;1433&quot;</span> 
<span class="attr">allowedPipes</span><span class="kwrd">=&quot;sql/query&quot;</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">hostMappings</span><span class="kwrd">&gt;</span>
  <span class="kwrd">&lt;/</span><span class="html">portBridge</span><span class="kwrd">&gt;</span></pre>
<style>
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode, .ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode pre
{margin:0em;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .rem
{color:#008000;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .str
{color:#006080;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .op
{color:#0000c0;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .html
{color:#800000;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass3BAB0B189751409A9F555FF71DB8CDC2 .csharpcode .lnum
{color:#606060;}
</style>
<p>NB: The Windows Azure instances do not have a copy of the Microsoft.ServiceBus.dll assembly installed in the GAC. Therefore to ensure that the application will run correctly, a copy of this assembly must be deployed as part of the package. This is achieved by setting the “Copy Local” property to true. This is one of the differences between the development fabric and the live Windows Azure instance.</p>
<p><a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/ConnectingtoSQLAzurewithoutchangingyourf_E3B6/image_16.png"><img width="465" height="272" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="Port Bridge in Windows Azure" border="0" alt="Port Bridge in Windows Azure" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/ConnectingtoSQLAzurewithoutchangingyourf_E3B6/image_thumb_4.png"></a> </p>
<p>With the Port Bridge Service deployed to a worker role, I can now connect to SQL Azure from my demo laptop without the challenges presented by firewalls. By using a Worker Role I also reduce the network latency as all the components are hosted in the Cloud. By ensuring that I select the same data centre i.e. North Europe for all three components, this adds very little latency to the whole communication compared to direct SQL Azure access.</p>

</div>]]></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">DOTNETSOL\Marcus</dc:creator><pubDate>Wed, 03 Mar 2010 12:07:00 GMT</pubDate><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Azure/">Azure</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/SQL Server/">SQL Server</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Dev Tools/">Dev Tools</category></item><item><title>Windows Azure Diagnostics – Why the Trace.WriteLine method only sends Verbose messages</title><link>http://www.dotnetsolutions.co.uk/blog/archive/2010/02/22/windows-azure-diagnostics-–-why-the-trace-writeline-method-only-sends-verbose-messages/</link><guid isPermaLink="False">/blog/archive/2010/02/22/windows-azure-diagnostics-–-why-the-trace-writeline-method-only-sends-verbose-messages/</guid><description><![CDATA[<div class="ExternalClassBB2608E444E347B8801B08B5D2FDC179">
<p>Logging diagnostic information plays a key part for any application. The .Net framework provides a number of Diagnostic features, which can be used to provide logging functionality in your application.</p>
<p>However, in Windows Azure, the diagnostic API available in early CTPs was very limited. In the November release of Windows Azure, a new feature for  Windows Azure Diagnostics was launched. I will not delve into details of how to use the Azure diagnostic API. You can read about this <a href="http://blogs.msdn.com/sumitm/archive/2009/11/18/introducing-windows-azure-diagnostics.aspx">here</a> and also <a href="http://nmackenzie.spaces.live.com/blog/cns!B863FF075995D18A!536.entry?wa=wsignin1.0&amp;sa=918959033">here</a>.</p>
<p>In this article, I will be focusing only on a recent challenge we came across while implementing the Windows Azure Diagnostics API for ScrumWall (<a href="http://scrumwall.cloudapp.net">http://scrumwall.cloudapp.net</a>). ScrumWall uses a factory pattern to determine which concrete log writer to use. It had both a trace listener logger and a custom Windows Azure Table storage logger. The trace listeners implementation could be configured in web.config. </p>
<p>The section for trace listeners in web.config for ScrumWall is:</p>
<div class="csharpcode">
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">system.diagnostics</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">switches</span><span class="kwrd">&gt;</span>
      <span class="rem">&lt;!-- Off = 0, Error 1, Warning = 2, Info = 3,</span></pre>
<pre class="csharpcode"><span class="rem"> Verbose = 4 --&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">name</span><span class="kwrd">=&quot;logLevel&quot;</span> <span class="attr">value</span><span class="kwrd">=&quot;2&quot;</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">switches</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">trace</span> <span class="attr">autoflush</span><span class="kwrd">=&quot;true&quot;</span> <span class="attr">indentsize</span><span class="kwrd">=&quot;2&quot;</span><span class="kwrd">&gt;</span>
      <span class="kwrd">&lt;</span><span class="html">listeners</span><span class="kwrd">&gt;</span>
       <span class="rem">&lt;!-- add file logger outside Azure --&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">name</span><span class="kwrd">=&quot;TextWriterTraceListener&quot;</span> 
             <span class="attr">type</span><span class="kwrd">=&quot;System.Diagnostics.TextWriterTraceListener&quot;</span> 
             <span class="attr">initializeData</span><span class="kwrd">=&quot;TextWriterOutput.log&quot;</span><span class="kwrd">/&gt;</span>
      <span class="kwrd">&lt;/</span><span class="html">listeners</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">trace</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">system.diagnostics</span><span class="kwrd">&gt;</span> 
</pre>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
<pre></pre>
</div>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
<p>A static Logger class provides a facade which writes to the underlying trace listeners using the static overloaded method of System.Diagnostics.Trace class WriteLine(string message) using our TraceListenerLogWriter:</p>
<div class="csharpcode">
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> TraceListenerLogWriter : ILogWriter
{
    <span class="kwrd">private</span> <span class="kwrd">static</span> TraceSwitch _logLevelConfigured = 
        <span class="kwrd">new</span> TraceSwitch(<span class="str">&quot;logLevel&quot;</span>, <span class="str">&quot;Switch log level&quot;</span>);

    <span class="kwrd">public</span> <span class="kwrd">void</span> WriteLog(<span class="kwrd">string</span> message)
    {
        Trace.WriteLine(message);
    }

    <span class="kwrd">public</span> <span class="kwrd">bool</span> ShouldLog(TraceLevel traceLevel)
    {
        <span class="kwrd">if</span> ((<span class="kwrd">int</span>)_logLevelConfigured.Level &gt;= (<span class="kwrd">int</span>)traceLevel)
        {
            <span class="kwrd">return</span> <span class="kwrd">true</span>;
        }
        <span class="kwrd">else</span>
        {
            <span class="kwrd">return</span> <span class="kwrd">false</span>;
        }
    }
}
</pre>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
</div>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
<p>The Windows Azure trace listener is provided by “DiagnosticMonitorTraceListener”, which we added in the existing web.config :</p>
<pre class="csharpcode"><span class="rem">&lt;!-- add file logger for Azure --&gt;</span>
<span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">type</span><span class="kwrd">=&quot;Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener, Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&quot;</span>
     <span class="attr">name</span><span class="kwrd">=&quot;AzureDiagnostics&quot;</span><span class="kwrd">&gt;</span>          
<span class="kwrd">&lt;/</span><span class="html">add</span><span class="kwrd">&gt;</span></pre>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
<p>and in our WebRole, which  is responsible for Diagnostic Monitor start up, we have the following Diagnostic configuration.</p>
<div class="csharpcode">
<pre class="csharpcode"><span class="rem">//set Trace logs to Warning and above every 5 minutes </span>
DiagnosticMonitorConfiguration dmc = 
     DiagnosticMonitor.GetDefaultInitialConfiguration(); 
 
dmc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(5);   
dmc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Warning;  

DiagnosticMonitor.Start(<span class="str">&quot;DiagnosticsConnectionString&quot;</span>, dmc); 
</pre>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
</div>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
<p>A very odd behaviour was observed when running the application, it would only store Verbose level messages. When setting the Diagnostic monitor log level filter for Warning no log messages were logged.</p>
<p>It was quite a puzzle! </p>
<h3>How are we filtering our trace messages?</h3>
<p>In configuration, a TraceSwitch is defined called “logLevel”. The static Logger applies the filter using the ShouldLog method of TraceListenerLogWriter. All of the attached listeners then receive trace messages appropriate to the filter. </p>
<p>However, Azure Diagnostic has another level of filtering, which is used to send the logged messages to Azure storage at a particular interval defined through DiagnosticMonitorConfiguration.</p>
<p>You might still be wondering why this filtering will affect it.</p>
<h3>How is the Trace.WriteLine method in DiagnosticMonitorTraceListener class implemented?</h3>
<p>As explained earlier that Azure Diagnostic operates with two levels of filtration:</p>
<p>a. Filter for logging to attached trace listeners.</p>
<p>b. Filter for sending the logged messages to Azure storage.</p>
<p>The underlying logger requires the log level in message so that the filter can be applied before sending to Azure storage. </p>
<p>But looking at the DiagnosticMonitorTraceListener class in Reflector, the WriteLine method calls an overridden method Write, which is <em>hijacked </em>to be Verbose only:</p>
<div class="csharpcode">
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Write(<span class="kwrd">string</span> message)   
{   
    <span class="kwrd">this</span>.WriteStringEtw(TraceEventType.Verbose, 0, message);   
}
</pre>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
</div>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
<p>The use of Verbose does make sense, as a default value for use by the second level filter. But this is hidden inside the implementation of the trace listener. This is why just replacing the trace listener did not work for our application.</p>
<h3>What is the solution?</h3>
<p>The solution is quite straightforward. Instead of using Trace.WriteLine, use Trace.TraceError, Trace.TraceWarning, Trace.TraceInformation appropriately and Trace.WriteLine for the Verbose event.</p>
<p>The modified version of our TraceListenerLogWriter looks like : </p>
<div class="csharpcode">
<div class="csharpcode">
<pre><span class="lnum"></span></pre>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> TraceListenerLogWriter : ILogWriter   
{  
    <span class="kwrd">public</span> <span class="kwrd">void</span> WriteLog(TraceLevel level, <span class="kwrd">string</span> message)   
    {  
        <span class="kwrd">switch</span> (tracelevel)   
        {  
            <span class="kwrd">case</span> TraceLevel.Error:  
                Trace.TraceError(message);  
                <span class="kwrd">break</span>;  
            
            <span class="kwrd">case</span> TraceLevel.Warning:
                Trace.TraceWarning(message); 
                <span class="kwrd">break</span>;  
            
            <span class="kwrd">case</span> TraceLevel.Info: 
                Trace.TraceInformation(message);
                <span class="kwrd">break</span>;  
            
            <span class="kwrd">case</span> TraceLevel.Verbose:
                Trace.WriteLine(message);
                <span class="kwrd">break</span>;
            
            <span class="kwrd">default</span>:
            <span class="rem">//no logging</span>
            <span class="kwrd">break</span>;
        }  
    }
} 
</pre>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
</div>
<style>
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode, .ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode pre
{margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .rem
{color:#008000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .str
{color:#006080;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .op
{color:#0000c0;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .preproc
{color:#cc6633;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .html
{color:#800000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .attr
{color:#ff0000;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClass63D137CD258244798E6353CB0B51D6C2 .csharpcode .lnum
{color:#606060;}
</style>
</div>
<p>In summary, only use the Trace.WriteLine method to log Verbose messages. Keep in mind that Trace.WriteLine is <em>Trace.TraceVerbose </em>within the Azure trace listener.</p>

</div>]]></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">DOTNETSOL\SharepointSA</dc:creator><pubDate>Mon, 22 Feb 2010 09:49:00 GMT</pubDate><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Azure/">Azure</category></item><item><title>Working with namespaces in LINQ to XML</title><link>http://www.dotnetsolutions.co.uk/blog/archive/2010/02/17/working-with-namespaces-in-linq-to-xml/</link><guid isPermaLink="False">/blog/archive/2010/02/17/working-with-namespaces-in-linq-to-xml/</guid><description><![CDATA[<div class="ExternalClassDD9B70F74BCD45A692618C585FD62F83">
<p>Read more about work on an Azure utility, which had to deal with the XML responses provided by the Service Management REST API: <a href="http://www.dotnetsolutions.co.uk/blogs/markrendle/archive/2010/02/17/working-with-namespaces-in-linq-to-xml" title="http://www.dotnetsolutions.co.uk/blogs/markrendle/archive/2010/02/17/working-with-namespaces-in-linq-to-xml/">http://www.dotnetsolutions.co.uk/blogs/markrendle/archive/2010/02/17/working-with-namespaces-in-linq-to-xml/</a> on Mark Rendle’s new blog here: <a href="http://www.dotnetsolutions.co.uk/blogs/markrendle" title="http://www.dotnetsolutions.co.uk/blogs/markrendle">http://www.dotnetsolutions.co.uk/blogs/markrendle</a>.</p>

</div>]]></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">DOTNETSOL\SharepointSA</dc:creator><pubDate>Wed, 17 Feb 2010 11:55:00 GMT</pubDate><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Azure/">Azure</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/XML/">XML</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/LINQ/">LINQ</category></item><item><title>How to migrate ScrumWall to Azure in less than 20 minutes</title><link>http://www.dotnetsolutions.co.uk/blog/archive/2010/02/17/how-to-migrated-scrumwall-to-azure-in-less-than-20-minutes/</link><guid isPermaLink="False">/blog/archive/2010/02/17/how-to-migrated-scrumwall-to-azure-in-less-than-20-minutes/</guid><description><![CDATA[<div class="ExternalClass792DD6699AF548C19FD3CA905ED35AC9">
<p>This post should really be title: “how we <strong>(could have)</strong> migrated ScrumWall to Azure in less than 20 minutes”. But I’ll come on to that later.</p>
<p>I’ve been speaking about Azure at a number of events recently. As part of the talks, I have given a quick overview of the developer portal for Azure and the Visual Studio tools. I’ve wrapped this up in a demo using our ScrumWall product (<a href="http://scrumwall.cloudapp.net" target="_blank">http://scrumwall.cloudapp.net</a>).</p>
<p>Winding back time conveniently to about a year ago, I explain how we could have migrated ScrumWall to Azure in less than 20 minutes. I then go on to highlight some of the additional requirements that would be required to enable this to be managed, supported and maintained in production.</p>
<h2>The Demo</h2>
<p>The majority of functionality provided by ScrumWall is contained in a Silverlight application. There are a number of WCF services to provide data to this application and some fairly basic ASP.NET pages. There are also a couple of HTTP handlers to manage the authentication, which is provide by Microsoft Live ID.</p>
<p>Overall ScrumWall contains a reasonable number of different components and is a good “test” candidate to migrate to Azure.</p>
<h3>Step 1: Creating the SQL Azure Database</h3>
<p>Using the “Generate Script” option to script the whole database (including the triggers used for audit) produces something very close to the SQL needed e.g. for the Story table the following SQL is generated:</p>
<style>
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode, .ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .rem
{color:#008000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .str
{color:#006080;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .op
{color:#0000c0;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .html
{color:#800000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .attr
{color:#ff0000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .lnum
{color:#606060;}
</style>
<pre class="csharpcode"><span class="kwrd">CREATE</span> <span class="kwrd">TABLE</span> [dbo].[Story](
    [StoryId] &lt;removed_for_clarity&gt;
 <span class="kwrd">CONSTRAINT</span> [PK_Story] <span class="kwrd">PRIMARY</span> <span class="kwrd">KEY</span> <span class="kwrd">CLUSTERED</span> 
(
    [StoryId] <span class="kwrd">ASC</span>
)<span class="kwrd">WITH</span> (PAD_INDEX  = <span class="kwrd">OFF</span>, STATISTICS_NORECOMPUTE  = <span class="kwrd">OFF</span>, IGNORE_DUP_KEY = <span class="kwrd">OFF</span>,
 ALLOW_ROW_LOCKS  = <span class="kwrd">ON</span>, ALLOW_PAGE_LOCKS  = <span class="kwrd">ON</span>) <span class="kwrd">ON</span> [<span class="kwrd">PRIMARY</span>]
) <span class="kwrd">ON</span> [<span class="kwrd">PRIMARY</span>]
GO</pre>
<p>This can be modified as follow to make is SQL Azure compatible:</p>
<pre class="csharpcode"><span class="kwrd">CREATE</span> <span class="kwrd">TABLE</span> [dbo].[Story](
    [StoryId] &lt;removed_for_clarity&gt;
 <span class="kwrd">CONSTRAINT</span> [PK_Story] <span class="kwrd">PRIMARY</span> <span class="kwrd">KEY</span> <span class="kwrd">CLUSTERED</span> 
(
    [StoryId] <span class="kwrd">ASC</span>
)
)
GO</pre>
<style>
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode, .ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .rem
{color:#008000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .str
{color:#006080;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .op
{color:#0000c0;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .html
{color:#800000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .attr
{color:#ff0000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode, .ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .rem
{color:#008000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .str
{color:#006080;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .op
{color:#0000c0;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .html
{color:#800000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .attr
{color:#ff0000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .lnum
{color:#606060;}
</style>
<p>Any data that needs to be migrated can be scripted (as this is a small application).</p>
<h3>Step 2: Update the web.config</h3>
<p>The existing connection string is simply replace with a new one, ensuring that encrypt is set to true:</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">name</span><span class="kwrd">=&quot;ScrumwallConnectionString&quot;</span>
    <span class="attr">connectionString</span><span class="kwrd">=&quot;Data Source=v2wqed1zpx.database.windows.net;<br>Initial Catalog=ScrumWall; User ID=scrumwall@v2wqed1zpx;Password=password;<br>Trusted_Connection=false;Encrypt=true;&quot;</span>
    <span class="attr">providerName</span><span class="kwrd">=&quot;System.Data.SqlClient&quot;</span> <span class="kwrd">/&gt;</span></pre>
<style>
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode, .ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .rem
{color:#008000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .str
{color:#006080;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .op
{color:#0000c0;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .html
{color:#800000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .attr
{color:#ff0000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .lnum
{color:#606060;}
</style>
<style>
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode, .ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .rem
{color:#008000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .str
{color:#006080;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .op
{color:#0000c0;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .html
{color:#800000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .attr
{color:#ff0000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .lnum
{color:#606060;}
</style>
<h3>Step 3: Creating a Cloud Project</h3>
<p>To migrate the ASP.NET application project to Azure, first I add a new Windows Azure Cloud Service project with no Web or Worker roles. Then by using the option to add a Web Role project from the solution, I can associate the existing ASP.NET project with the Cloud Service project.</p>
<p><a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/DemohowwemigratedScrumWalltoAzureinlesst_ABDA/Untitled_2.jpg"><img width="244" height="162" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="Untitled" border="0" alt="Untitled" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/DemohowwemigratedScrumWalltoAzureinlesst_ABDA/Untitled_thumb.jpg"></a> </p>
<p>Testing this locally in the Development Fabric means using a different port, port 81 for my machine. In order to ensure that Live ID redirects my authenticated users back to the correct place I need to create a new Live Services application ID (<a href="https://live.azure.com/" title="https://live.azure.com/" target="_blank">https://live.azure.com/</a>). I have used the “domain” of “azure.machine.local” and the return URL “http://azure.machine.local:81/LiveAuthHandler.ashx”. Next I add an entry into to my hosts file, a mapping of host name “azure.machine.local” to 127.0.0.1. Last, the web.config is updated with the new application ID and secret:</p>
<pre class="csharpcode">    <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">key</span><span class="kwrd">=&quot;wll_appid&quot;</span> <span class="attr">value</span><span class="kwrd">=&quot;0000000044028C05&quot;</span><span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">key</span><span class="kwrd">=&quot;wll_secret&quot;</span> <span class="attr">value</span><span class="kwrd">=&quot;x1x1x1x1x1x1x1x1x1x1x1&quot;</span><span class="kwrd">/&gt;</span></pre>
<style>
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode, .ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{font-size:small;color:black;font-family:consolas, &quot;Courier New&quot;, courier, monospace;background-color:#ffffff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode pre
{margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .rem
{color:#008000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .kwrd
{color:#0000ff;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .str
{color:#006080;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .op
{color:#0000c0;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .preproc
{color:#cc6633;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .asp
{background-color:#ffff00;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .html
{color:#800000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .attr
{color:#ff0000;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .alt
{background-color:#f4f4f4;width:100%;margin:0em;}
.ExternalClassEEE2C83D39B949278E372571AEE91414 .csharpcode .lnum
{color:#606060;}
</style>
<p>I can now run the application on my local Development Fabric.</p>
<h3>Step 4: Deploying to Azure</h3>
<p>The migration is nearly finished. However, before I can publish this application to Azure, I need to create another Live Services application ID for the final domain “scrumwall.cloudapp.net” and once more update the web.config.</p>
<p>The application can now be published to Windows Azure and deployed. To ensure that the Windows Azure application can connect to SQL Azure, tick the Allow Microsoft Services access to this server.</p>
<p><a href="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/DemohowwemigratedScrumWalltoAzureinlesst_ABDA/image_4.png"><img width="244" height="58" style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px" title="image" border="0" alt="image" src="http://www.dotnetsolutions.co.uk/blog/Media/WindowsLiveWriter/DemohowwemigratedScrumWalltoAzureinlesst_ABDA/image_thumb_1.png"></a> </p>
<p>All of these steps including running the newly migrated project by clicking the <a href="http://scrumwall.cloudapp.net" target="_blank">http://scrumwall.cloudapp.net</a> can be completed in less than 20 minutes!</p>
<h2>The Real World</h2>
<p>Now in the real world, there are a significant number of real world questions that you need to ask before migrating an application to Azure, for a fuller list check out this book: <a href="http://www.dotnetsolutions.co.uk/blog/archive/2009/11/04/“thinking-of-delivering-solutions-on-the-windows-azure-platform”-book-now-published" title="http://www.dotnetsolutions.co.uk/blog/archive/2009/11/04/“thinking-of-delivering-solutions-on-the-windows-azure-platform”-book-now-published/">http://www.dotnetsolutions.co.uk/blog/archive/2009/11/04/“thinking-of-delivering-solutions-on-the-windows-azure-platform”-book-now-published/</a>.</p>
<p>For ScrumWall there are three areas in particular that we chose to address as part of our real migration of ScrumWall to Azure:</p>
<ol>
    <li>Management of configuration values, in particular the Live Services application ID. This is discussed here: <a href="http://www.dotnetsolutions.co.uk/blog/archive/2009/04/23/moving-scrumwall-to-the-windows-azure-platform-part-3-windows-live" title="http://www.dotnetsolutions.co.uk/blog/archive/2009/04/23/moving-scrumwall-to-the-windows-azure-platform-part-3-windows-live/">http://www.dotnetsolutions.co.uk/blog/archive/2009/04/23/moving-scrumwall-to-the-windows-azure-platform-part-3-windows-live/</a> </li>
    <li>Use of Windows Azure Table storage in preference to SQL Azure. This is discussed in another previous blog: <a href="http://www.dotnetsolutions.co.uk/blog/archive/2009/02/24/moving-scrumwall-to-the-windows-azure-platform-(part-1-the-data)" title="http://www.dotnetsolutions.co.uk/blog/archive/2009/02/24/moving-scrumwall-to-the-windows-azure-platform-(part-1-the-data)/">http://www.dotnetsolutions.co.uk/blog/archive/2009/02/24/moving-scrumwall-to-the-windows-azure-platform-(part-1-the-data)/</a> </li>
    <li>Access to logging and diagnostic information. This has been significantly improved from the early CTP for v1 of Windows Azure and has been well covered elsewhere, for instance: <a href="http://blogs.msdn.com/windowsazure/archive/2009/12/01/introducing-windows-azure-diagnostics.aspx" title="http://blogs.msdn.com/windowsazure/archive/2009/12/01/introducing-windows-azure-diagnostics.aspx" target="_blank">http://blogs.msdn.com/windowsazure/archive/2009/12/01/introducing-windows-azure-diagnostics.aspx</a> </li>
</ol>
<h2>The Big Demo Challenge</h2>
<p>On a side note, one of the biggest challenges for the demo was actually connecting to SQL Azure from SQL Server Management Studio. Often firewalls will block port 1433/1434 outbound and this a major hassle to get changed, especially for a 20 minute demo. For more information on one approach to resolve this issue see my next blog post.</p>

</div>]]></description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">DOTNETSOL\SharepointSA</dc:creator><pubDate>Wed, 17 Feb 2010 10:31:00 GMT</pubDate><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Azure/">Azure</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Silverlight/">Silverlight</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/Scrum/">Scrum</category><category domain="http://www.dotnetsolutions.co.uk/blog/archive/tags/SQL Server/">SQL Server</category></item></channel></rss>