<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Musings on ALM and Software Development Processes</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:23:34 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>WIF10201: No valid key mapping found for securityToken: 'System.IdentityModel.Tokens.X509SecurityToken' and issuer: 'https://sts.windows.net/0f44c5d4-42b0-45c2-bf55-d0fea8430d33/'.</title>
      <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/wif10201-no-valid-key-mapping-found-for-securitytoken-system-identitymodel-tokens-x509securitytoken-and-issuer-httpssts-windows-net0f44c5d4-42b0-45c2-bf55-d0fea8430d33</link>
      <pubDate>Wed, 25 Feb 2015 19:52:00 GMT</pubDate>
      <dc:creator><![CDATA[Jeff Levinson (p)]]></dc:creator>
      <guid
        isPermaLink="false">http://qa.msdn.wdslab.com/musings_on_alm_and_software_development_processes/2015/02/25/wif10201-no-valid-key-mapping-found-for-securitytoken-system-identitymodel-tokens-x509securitytoken-and-issuer-httpssts-windows-net0f44c5d4-42b0-45c2-bf55-d0fea8430d33/</guid>
      <description><![CDATA[In my original blog post on enabling Azure Active Directory integration for an MVC application I...]]></description>
      <content:encoded><![CDATA[<p>In my <a href="http://blogs.msdn.com/b/musings_on_alm_and_software_development_processes/archive/2014/09/09/integrating-an-mvc-application-with-azure-active-directory-visual-studio-2013-and-being-able-to-deploy-it.aspx">original blog post</a> on enabling Azure Active Directory integration for an MVC application I realized that I left a few things out. I didn’t realize this though until one my customers started pulling their hair out because they couldn’t get it to work at all. After guiding them through the implementation they ran into the error in the title of this blog post. It turns out there were a number of things wrong and one thing I just couldn’t figure out because it wasn’t documented anywhere. And my first implementation avoided the problem altogether. This post will correct some holes so you can avoid this problem.</p>  <h1>Problem 1: The TenantId</h1>  <p>If this value is wrong, you’ll get the above error. So where do you get the tenantId from? I neglected to leave this out of my original post. So where does it come from and why did I leave it out of my original post? Let me reverse the questions. In my original post I created an application from scratch and enabled AAD integration which created a LocalDb with all of the data populated for me. That’s the easy way – what if you’re enabling an existing application (I did say I was going to get to that in a later post but I’ve been busy)? The TenantID can actually be found quite easily – you just have to know what to look for. In this case, the TenantID can be found by going to the Azure Portal (manage.windowsazure.com – this can’t be accessed from the Preview Portal just yet), clicking on the Active Directory link, clicking the directory that you are using (Default Directory in my case), clicking Applications and finally clicking the name of the application that you’ve integrated with AAD. Finally, at the bottom of the page click View Endpoints (on the icon bar at the bottom). That will display the dialog shown here:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8015.image_15486016.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8015.image_5F00_15486016.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0753.image_thumb_3DE6CC1D.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0753.image_5F00_thumb_5F00_3DE6CC1D.png" width="194" height="244" /></a> </p>  <p>In this dialog, focus on the WS-FEDERATION SIGN-ON ENDPOINT which looks like this in my case:</p>  <p><a title="https://login.windows.net/67c3a3d5-b264-4328-ade6-7a7b81136117/wsfed" href="https://login.windows.net/67c3a3d5-b264-4328-ade6-7a7b81136117/wsfed">https://login.windows.net/67c3a3d5-b264-4328-ade6-7a7b81136117/wsfed</a></p>  <p>The guid in this string is the TenantID and this is what goes in the single row in the Tenants table in the database (refer to the original post).</p>  <p>That’s one problem taken care of.</p>  <h2>Problem 2: The IssuingAuthorityKeys</h2>  <p>This one was a little more interesting and I have to say it is one of those things that is just not documented well anywhere. I came across it in a forum post as I was researching the problem. The original forum post is here (but it leaves out a couple of steps): <a title="https://social.msdn.microsoft.com/Forums/en-US/8f2b7807-8d49-4190-978c-535c91f440c4/no-valid-key-mapping-found-for-securitytokensystemidentitymodeltokensx509securitytoken?forum=WindowsAzureAD" href="https://social.msdn.microsoft.com/Forums/en-US/8f2b7807-8d49-4190-978c-535c91f440c4/no-valid-key-mapping-found-for-securitytokensystemidentitymodeltokensx509securitytoken?forum=WindowsAzureAD">https://social.msdn.microsoft.com/Forums/en-US/8f2b7807-8d49-4190-978c-535c91f440c4/no-valid-key-mapping-found-for-securitytokensystemidentitymodeltokensx509securitytoken?forum=WindowsAzureAD</a>. In this post there is a link to a documentation page here: <a title="https://msdn.microsoft.com/en-us/library/azure/dn641920.aspx" href="https://msdn.microsoft.com/en-us/library/azure/dn641920.aspx">https://msdn.microsoft.com/en-us/library/azure/dn641920.aspx</a>. This documentation is excellent but without the forum post I never would have found it – and as I said it leaves out a couple of steps. However, I urge everyone to read it because it has topics that cover why you might get the above error even though the application worked previously. <strong>Another item to note is that the suggestions for automatically handling key rollover for VS 2013 applications don’t make sense – my application was created with VS 2013 and it didn’t get the rollover logic. Read the section on VS 2012 and update your application accordingly so this problem won’t happen in the future.</strong></p>  <p>The key rollover problem occurs because Microsoft frequently creates new certificates to help mitigate any security issues and deal with the fact that certificates expire. But that leaves applications which depend on AAD integration in the lurch. So, how do you get the new key (or keys in this situation)? In the MSDN article referenced (in the section on manually updating your keys) above it tells you to navigate to the above dialog and copy the URL for the Federation Metadata Document and paste it into the address bar of your browser. It then tells you to find the x509Certificate element, copy the value of this element and save it as a .cer file (paste it into notepad and save the resulting file as key1.cer for example). After you do that you can double-click the file and view the details. On the Details tab it will give you the Thumbprint for the certificate and you’re good to go, right? Wrong – this is where the article gets it wrong. You need to do this <em>for each certificate in the response</em>. In this case there are now two keys that need to be entered into the IssuingAuthorityKeys table. </p>  <h1>In Conclusion</h1>  <p>One thing I haven’t figure out yet (more experimentation necessary) is that after making the changes to the code to automatically update the keys, it puts those thumbprints in the web.config file. I do not know if the database is needed at all after this. I will experiment some more and come back and update this post with additional information.</p>  <p>Hope this helps!</p>]]></content:encoded>
    </item>
    <item>
      <title>Release Management and DSC</title>
      <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/release-management-and-dsc</link>
      <pubDate>Fri, 21 Nov 2014 17:55:42 GMT</pubDate>
      <dc:creator><![CDATA[Jeff Levinson (p)]]></dc:creator>
      <guid
        isPermaLink="false">http://qa.msdn.wdslab.com/musings_on_alm_and_software_development_processes/2014/11/21/release-management-and-dsc/</guid>
      <description><![CDATA[This is the second post in a series. The first post can be found here.  In this post we’ll look at...]]></description>
      <content:encoded><![CDATA[<p>This is the second post in a series. The first post can be found <a href="http://blogs.msdn.com/b/musings_on_alm_and_software_development_processes/archive/2014/11/16/release-management-as-a-service.aspx">here</a>.</p>  <p>In this post we’ll look at three things – configuring a server from scratch, deploying the required PowerShell DSC modules and using variables in the PowerShell DSC scripts.</p>  <p><font style="background-color: #ffff00">Note</font></p>  <p>In the Windows Management Framework 5.0 which is currently in preview, the process for deploying DSC modules will (or can) change. More information on WMF 5.0 and the new PowerShell Gallery can be found <a href="http://www.powershellgallery.com/">here</a>. With WMF 5.0 you can execute the PowerShell command Install-Module –Name xxxx and the module will be installed directly from the gallery. The method being provided here can be used as an alternate if you don’t want to do this (also, I really wanted to show a clean installation without having to pre-install WMF 5.0).</p>  <h1>Deploying PowerShell DSC Modules as part of the Release and configuring the server from scratch</h1>  <p>Let’s start with the basics – a clean machine. I loaded up a new machine in Azure and did absolutely nothing with it except to add the http endpoint so I could check to see if the website actually installed successfully. The name of the server is, appropriately I think, “AppFromScratch”.</p>  <p>Next, I’m going to continue with the BlogDemo example from the previous post so if you haven’t read that, it’s probably good to skim it.</p>  <p>I’ll quickly go through the setup for this walkthrough. </p>  <ol>   <li>Create a new build called “BlogDemo From Scratch”</li>    <li>In the RM client I linked the new environment and server</li>    <li>I created a new path with only a Development environment pointed to the clean server</li> </ol>  <p>Next, I’ll go through the changes in the solution – specifically the DeploymentScripts project. At the end of this the project will look like that in Figure 1.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2502.image_4C8E2C9F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2502.image_5F00_4C8E2C9F.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/6327.image_thumb_012E88DB.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/6327.image_5F00_thumb_5F00_012E88DB.png" width="177" height="244" /></a></p>  <p>Figure 1 – Solution at the end of this section of the walkthrough</p>  <p>The first thing to do is to add the xWebAdministration PowerShell to source code. This is kind of a pain in the butt and I’m working on a better solution. The reason it’s a pain is because it requires you to go into every folder and mark each file as “Copy if newer”. But stay tuned for a more streamlined approach to be presented in a later blog. I’ll come back and update this post with a link.</p>  <p>The next thing to do is to add a new PowerShell script file called “CopyDscScript.ps1”. This script looks like the following:</p>  <pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  1: configuration FileCopy 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  2: {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  3:   node localhost
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  4:   {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  5:     File CopyDSCModules
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  6:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  7:       Ensure           = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  8:       Type             = &quot;<span style="color: #8b0000">Directory</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  9:       Recurse          = $<span style="color: #0000ff">true</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 10:       SourcePath       = join-path $applicationPath &quot;<span style="color: #8b0000">DSCModules</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 11:       DestinationPath  = &quot;<span style="color: #8b0000">C:\program files\WindowsPowerShell\Modules</span>&quot; 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 12:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 13:   }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 14: }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 15: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 16: FileCopy</pre></pre>

<p>This is a pretty basic DSC configuration – it just copies the DSCModules folder from the output location to one of the PowerShell module locations on the server (there are ways to get this value but in many cases they return multiple locations so it’s just hard-coded here as a safe location that’s always available).</p>

<p>Next, add a new deployment script called “DeploymentScript2.ps1” which looks like the following:</p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  1: configuration FullSetup 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  2: {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  3:   Import-DscResource -Module xWebAdministration
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  4: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  5:   node localhost
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  6:   {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  7:     WindowsFeature IIS
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  8:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  9:        Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 10:        Name            = &quot;<span style="color: #8b0000">Web-Server</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 11:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 12: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 13:     WindowsFeature ASPNet45
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 14:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 15:        Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 16:        Name            = &quot;<span style="color: #8b0000">Web-Asp-Net45</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 17:        DependsOn       = &quot;<span style="color: #8b0000">[WindowsFeature]IIS</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 18:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 19: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 20:     File CopyDeploymentBits
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 21:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 22:       Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 23:       Type            = &quot;<span style="color: #8b0000">Directory</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 24:       Recurse         = $<span style="color: #0000ff">true</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 25:       SourcePath      = join-path $applicationPath &quot;<span style="color: #8b0000">_PublishedWebsites</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 26:       DestinationPath = &quot;<span style="color: #8b0000">C:\inetpub\wwwroot</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 27:       DependsOn       = &quot;<span style="color: #8b0000">[WindowsFeature]ASPNet45</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 28:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 29: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 30:     xWebsite DefaultSite
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 31:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 32:        Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 33:        Name            = &quot;<span style="color: #8b0000">Default Web Site</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 34:        State           = &quot;<span style="color: #8b0000">Stopped</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 35:        PhysicalPath    = &quot;<span style="color: #8b0000">C:\inetpub\wwwroot</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 36:        DependsOn       = &quot;<span style="color: #8b0000">[File]CopyDeploymentBits</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 37:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 38: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 39:     xWebsite NewWebsite
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 40:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 41:        Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 42:        Name            = &quot;<span style="color: #8b0000">BlogDemo</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 43:        State           = &quot;<span style="color: #8b0000">Started</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 44:        PhysicalPath    = &quot;<span style="color: #8b0000">c:\inetpub\wwwroot\BlogDemo</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 45:        DependsOn       = &quot;<span style="color: #8b0000">[xWebsite]DefaultSite</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 46:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 47:   }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 48: }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 49: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 50: FullSetup</pre></pre>

<p>The only thing different in this listing than the DeploymentScript1 from the previous blog post is that (well, besides the fact that I changed the name of the configuration to “FullSetup” since it more accurately describes the script) I added the installation of the IIS server and ASP.NET 4.5 as noted between lines 7 and 18.</p>

<p>Save all of this and check it into source control.</p>

<p>Next up is the release template. I created a new template called BlogDemo from Scratch which is shown in Figure 2.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0385.image_67C685A0.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0385.image_5F00_67C685A0.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7713.image_thumb_5C30C861.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7713.image_5F00_thumb_5F00_5C30C861.png" width="244" height="158" /></a></p>

<p>Figure 2 – New Release Template</p>

<p>In this template there are two “Deploy Using PS/DSC” actions which I’ve renamed to illustrate their purpose. The configuration of both is identical except that I’m calling a different script. In the first one I’m deploying the DSC Module(s) and in the second I’m performing the server setup and deploying the application. You can of course break these up however you wish. </p>

<p>The beauty of DSC is that if IIS is already installed or ASP.NET 4.5 is already installed, those steps are skipped. This means that the second time I deploy to this server it will go much faster. In addition this servers as a communication point with Operations. Hence the new industry buzzword of “DevOps”. Anybody from Operations can see that this requires a web server with ASP.NET 4.5 installed.</p>

<h1></h1>

<h1>Using variables in the PowerShell script</h1>

<p>Up to this point everything has been hard-coded. As this is a fairly simple application there isn’t a huge need to parameterize the file but in any reasonably complex environment this is almost a requirement. In this section I’ll show you how to parameterize the physical path of the website because while it might be fine to deploy the web application c:\inetpub\wwwroot\BlogEngine it isn’t likely that Operations wants you to deploy your website their for numerous reasons. By parameterizing this value it can be changed per environment as needed.</p>

<p>There are two ways to do this. You can add the variable to the component (New Component 1 in this case) or you can add it directly into the action on the release design surface. The reason for the different approaches is that by adding the variable to the component it is available to all releases which use that component. Adding the variable to the release template makes it available only to that release. In this case I’ll add it to the component.</p>

<p>On the Configure Apps tab, select the Component page and edit New Component 1. On the Configuration Variables page add a new variable called physicalPath as shown in Figure 3.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/6242.image_1BFAAEE7.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/6242.image_5F00_1BFAAEE7.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3108.image_thumb_307FFE65.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3108.image_5F00_thumb_5F00_307FFE65.png" width="244" height="82" /></a></p>

<p>Figure 3 – New configuration variable</p>

<p>Save and close the component and jump over to the release template.</p>

<p>Expand the activity that deploys the application and click the green + under Custom Configuration. The physicalPath variable will be available for you in the drop down for the first path. Select it and then add the path in the second column as shown in Figure 4.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3122.image_1064F1A8.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3122.image_5F00_1064F1A8.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/1067.image_thumb_1E3737A3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/1067.image_5F00_thumb_5F00_1E3737A3.png" width="227" height="244" /></a></p>

<p>Figure 4 – Configuration variable used as part of a release template</p>

<p>To add a variable in the release template without adding it to the component you would just type the name in the first column here but otherwise everything would be the same.</p>

<p>Next, go back and edit the DeploymentScript2 as follows:</p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  1: configuration FullSetup 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  2: {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  3:   Import-DscResource -Module xWebAdministration
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  4: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  5:   node localhost
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  6:   {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  7:     WindowsFeature IIS
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  8:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  9:         Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 10:         Name            = &quot;<span style="color: #8b0000">Web-Server</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 11:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 12: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 13:     WindowsFeature ASPNet45
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 14:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 15:         Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 16:         Name            = &quot;<span style="color: #8b0000">Web-Asp-Net45</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 17:         DependsOn       = &quot;<span style="color: #8b0000">[WindowsFeature]IIS</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 18:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 19: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 20:     File CopyDeploymentBits
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 21:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 22:         Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 23:         Type            = &quot;<span style="color: #8b0000">Directory</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 24:         Recurse         = $<span style="color: #0000ff">true</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 25:         SourcePath      = join-path $applicationPath &quot;<span style="color: #8b0000">_PublishedWebsites</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 26:         DestinationPath = $physicalPath
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 27:         DependsOn       = &quot;<span style="color: #8b0000">[WindowsFeature]ASPNet45</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 28:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 29: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 30:     xWebsite DefaultSite
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 31:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 32:         Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 33:         Name            = &quot;<span style="color: #8b0000">Default Web Site</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 34:         State           = &quot;<span style="color: #8b0000">Stopped</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 35:         PhysicalPath    = &quot;<span style="color: #8b0000">C:\inetpub\wwwroot</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 36:         DependsOn       = &quot;<span style="color: #8b0000">[File]CopyDeploymentBits</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 37:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 38: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 39:     xWebsite NewWebsite
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 40:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 41:         Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 42:         Name            = &quot;<span style="color: #8b0000">BlogDemo</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 43:         State           = &quot;<span style="color: #8b0000">Started</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 44:         PhysicalPath    = join-path $physicalPath &quot;<span style="color: #8b0000">BlogDemo</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 45:         DependsOn       = &quot;<span style="color: #8b0000">[xWebsite]DefaultSite</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 46:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 47:   }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 48: }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 49: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 50: FullSetup</pre></pre>

<p>The specific changes are on lines 26 and 44. The reason line 35 wasn’t changed is because that’s the physical path of the default website and we don’t have any control over that (it’s also a different location than where we might put our website). </p>

<p>Check the change in and when the new release kicks off the website will have been updated successfully.</p>

<p>Hopefully this post has given you some more insight into what you can do with DSC and RM. In the next post I’ll expand this to a more typical scenario which will provide for deploying a database as part of the release. After that, well, we’ll see as there are a lot of places to go with this…</p>]]></content:encoded>
    </item>
    <item>
      <title>Release Management as a Service</title>
      <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/release-management-as-a-service</link>
      <pubDate>Sun, 16 Nov 2014 15:10:28 GMT</pubDate>
      <dc:creator><![CDATA[Jeff Levinson (p)]]></dc:creator>
      <guid
        isPermaLink="false">http://qa.msdn.wdslab.com/musings_on_alm_and_software_development_processes/2014/11/16/release-management-as-a-service/</guid>
      <description><![CDATA[This post provides a quick overview of the Release Management Service (in Preview) just announced on...]]></description>
      <content:encoded><![CDATA[<p>This post provides a quick overview of the Release Management Service (in Preview) just announced on November 12th. In addition I will walk you through doing a deployment to three environments in Azure using the service. This walkthrough requires that you have the Release Management client for Visual Studio Update 4. Finally, there are still some issues being worked and I’ll let you know about some of the gotcha’s I’ve run into – the product team is aware of all of them and they should be fixed by the time the service is out of preview.</p>  <h1>Overview</h1>  <p>For those who haven’t used or heard of Release Management, it is a part of Microsoft’s DevOps strategy to help enable the three ways made popular by the book The Phoenix Project. There are other parts such as the automated testing, automated builds and App Insights. Depending on what technologies you are using there may be other technologies that play into this story but these are the four core ones. In this post I’ll be talking specifically about RM and a little bit about team build since I have tied them together (Team Build is not a requirement to use RM).</p>  <p>At its core, RM can turn on environments, configure them through various means (we’ll look at using Desired State Configuration or DSC in this post), deploy your application across as many servers as needed and then execute a series of tests. It allows for a gated approval process which is controlled and auditable.</p>  <p>In this series of posts I will walk you through using RM with DSC and Visual Studio Online (hint, if you know how to use it on-premises you know how to use it in the cloud). We’ll start small and simple at first and work our way to more complex, more real-world examples such as multi-tier deployments.</p>  <h1>Connecting to Visual Studio Online</h1>  <p>In a large part it’s pretty underwhelming because it just works – which is the way it should be. The only pre-requisite for this is that you have a Visual Studio Online (VSO) account and that there is a Team Project already created. When RM launches the first time you’ll be asked to enter a URL. Simply enter your VSO URL (in my case jefflevinson.visualstudio.com) and click OK as shown in Figure 1 (note the URL is different because this is the fully qualified URL but you can just enter the shortened version).</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5756.image_2948F235.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5756.image_5F00_2948F235.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8484.image_thumb_0040E3EA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8484.image_5F00_thumb_5F00_0040E3EA.png" width="244" height="157" /></a></p>  <p>Figure 1 – Configuring the RM Service</p>  <p>The first thing you’ll want to do is to avoid a specific bug I discovered. To do this, go to the Administration &gt; Manage Users screen. Change the “Admin” account to your name as shown in Figure 2 (Admin was changed to Jeff Levinson).</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3286.image_0E1329E5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3286.image_5F00_0E1329E5.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4101.image_thumb_38EB8DF7.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4101.image_5F00_thumb_5F00_38EB8DF7.png" width="244" height="82" /></a></p>  <p>Figure 2 – RM Users</p>  <p><font style="background-color: #ffff00">**Warning**</font></p>  <p>There is currently a known issue here – DO NOT change the e-mail address of the Release Management Service no matter what. You will lock yourself out of the RM Service and will have to open a ticket with the VSO service which may take a little while to fix. The team is currently aware of this issue.</p>  <h1>Connecting to Azure Environments</h1>  <p>The next step is to set up your Azure environments for each stage of the deployment process. There is a definite structure you need to follow to get the most out of this. Each environment needs to be hosted in a separate cloud service. Whether or not they are in the same subscription is immaterial. For the purpose of this demonstration I have created three virtual machines in three different cloud services (you can have more than one machine in a cloud service but make sure each cloud service contains one environment). The names, for this series, are MyApplication1Dev, MyApplication1Test and MyApplication1 (which represents the production environment). The virtual machine names are all the same – MyApplication1 which is permitted <em>because</em> they are in different cloud service environments. This is obviously an optimal situation if you are running tests from the local servers. If you are running tests from another machine, consider putting a client machine in each cloud service – if you access these machines external of the environments you have to use the fully qualified name which means you have to parameterize the URL’s (i.e. you have to access them with <a href="http://myapplication1dev.cloudapp.net">http://myapplication1dev.cloudapp.net</a>).</p>  <p>One note, for our purposes (and probably yours as well) is that I have opened up port 80 for each of the VM’s in order to be able to see the changes on the website in the VM without having to log into the VM.</p>  <p>Once you have the Azure virtual machines created you can go to town in Release Management.</p>  <p>To being, go to the Configure Paths tab, Environments page (Figure 3).</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/6232.image_74AB26AA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/6232.image_5F00_74AB26AA.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/6254.image_thumb_62625FE8.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/6254.image_5F00_thumb_5F00_62625FE8.png" width="244" height="94" /></a></p>  <p>Figure 3 – Environments page</p>  <p>Click New vNext: Azure in the upper right which will bring up the new Azure Environments page as shown in Figure 4.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0410.image_09307629.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0410.image_5F00_09307629.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4604.image_thumb_48FA5CAE.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4604.image_5F00_thumb_5F00_48FA5CAE.png" width="244" height="154" /></a></p>  <p>Figure 4 – New Environment page</p>  <p>Click Clink Azure Environment in the upper right. Select the subscription to use, select the cloud service and click Link (Figure 5).</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2068.image_6FC872EE.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2068.image_5F00_6FC872EE.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2465.image_thumb_68A93676.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2465.image_5F00_thumb_5F00_68A93676.png" width="244" height="76" /></a></p>  <p>Figure 5 – Linking an existing cloud service</p>  <p>You can add as many subscriptions as you like from the Administration &gt; Manage Azure page. And this requires a small aside so it’s easier to do. The easiest way to get the required information is to grab the publishing profile for your azure subscription. To do this, go to <a title="https://manage.windowsazure.com/publishsettings/index?client=powershell" href="https://manage.windowsazure.com/publishsettings/index?client=powershell">https://manage.windowsazure.com/publishsettings/index?client=powershell</a>. This will trigger a file download which will allow you to save your publishing profile. This file contains all of the information you need to link RM to your subscription. This screen is shown in Figure 6.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0336.image_6AE5BF32.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0336.image_5F00_6AE5BF32.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7282.image_thumb_5F5001F3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7282.image_5F00_thumb_5F00_5F5001F3.png" width="244" height="96" /></a></p>  <p>Figure 6 – New Azure Subscription link page</p>  <p>The name can be arbitrary. The Subscription ID is included in the file and the Management Certificate Key is the whole string contained in the ManagementCertificate element of the publishing profile. The storage account is whatever storage account you want to use from Azure.</p>  <p>Okay, back to linking environments… After an environment is linked, click Link Azure Servers in the lower left of the window. Select one or more servers from the given cloud service and click OK. The resulting screen will look like that in Figure 7.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3808.image_21C2A42A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3808.image_5F00_21C2A42A.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2821.image_thumb_4C9B083C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2821.image_5F00_thumb_5F00_4C9B083C.png" width="244" height="154" /></a></p>  <p>Figure 7 – A linked environment with a single linked server</p>  <p>After linking however many cloud services you want, you’ll have an Environments screen that looks like those in Figure 8.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0361.image_6F5ED0AA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0361.image_5F00_6F5ED0AA.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8787.image_thumb_41054AFD.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8787.image_5F00_thumb_5F00_41054AFD.png" width="244" height="91" /></a></p>  <p>Figure 8 – Environments linked to RM</p>  <p>After doing this, click the Servers tab to review the cloud services and servers which are now linked to Release Management.</p>  <h2>Configuring the Release Path</h2>  <p>The next step is to configure the release path. To do that we need to specify which environments will be supported. Go to the Administration tab &gt; Manage Pick Lists and select the Stage Type entry. I have added the Dev, Test and Production entries as shown in Figure 9.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0876.image_2EBC843B.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0876.image_5F00_2EBC843B.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/1447.image_thumb_0377ED34.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/1447.image_5F00_thumb_5F00_0377ED34.png" width="244" height="101" /></a></p>  <p>Figure 9 – Stage Types</p>  <p>Once this has done we can now configure the actual release path which involves mapping the stage types to the environments. To do this, head to the Configure Paths &gt; vNext Release Paths page and click New. Enter the stages as needed. For each stage, click Add, select the stage label and then select the environment. The end result of this operation is shown in Figure 10.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4812.image_635CE076.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4812.image_5F00_635CE076.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/6558.image_thumb_6A0FE9F9.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/6558.image_5F00_thumb_5F00_6A0FE9F9.png" width="244" height="177" /></a></p>  <p>Figure 10 – A fully configured release path</p>  <p>The only absolutely critical thing about this is that the first stage (Development in this case) Acceptance Step must be set to Automated. The reason for this is that if it is manual and you trigger it from a build, the build will fail if it is not automated.</p>  <p>Once the release path is configured you’re ready to start building out the actual release process.</p>  <h2>Creating the Application</h2>  <p>We’ll create the ASP.NET MVC application next and structure it so that it is optimal for our purposes.</p>  <p>To begin with, create a new MVC project and change the authentication to “No Authentication”. In addition, uncheck the Host in Cloud checkbox (note that currently RM doesn’t support Azure Websites but it will in the future and you can make it work with Azure PowerShell scripting today but that’s a story for another day). I have opted to add unit tests to my project as is a best practice but that’s entirely up to you. The generated project structure looks like that in Figure 11.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3857.image_25CF82AD.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3857.image_5F00_25CF82AD.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4428.image_thumb_70C2F37C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4428.image_5F00_thumb_5F00_70C2F37C.png" width="244" height="208" /></a></p>  <p>Figure 11 – New MVC project</p>  <p>Note also that this is in version control in VSO which is required for this series of walkthrough’s. It is absolutely not a requirement to use RM in VSO – you can build code in any system and have RM deploy it but I’m not covering that in this series of posts.</p>  <p>Next, add a new Console Application project to the solution and call it “DeploymentScripts”. This is a quick and dirty way to get extra files deployed on build. There are various other options to accomplish this but this is by far the simplest. Delete the Program.cs file and change the output to Class Library. This project will contain any deployment scripts used for our application. The next step is to add in our DSC file. However, we’re going to edit it in PowerShell ISE as opposed to Visual Studio because there is no IntelliSense for Visual Studio at this time and I’ll show you a simple trick to figure out what functionality is available to you.</p>  <p>Open PowerShell ISE and copy and paste this script as follows:</p>        <pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  1: configuration FileCopy 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  2: {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  3:   Import-DscResource -Module xWebAdministration
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  4: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  5:   node localhost
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  6:   {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  7:     File CopyDeploymentBits
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  8:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  9:       Ensure           = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 10:       Type             = &quot;<span style="color: #8b0000">Directory</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 11:       Recurse          = $<span style="color: #0000ff">true</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 12:       SourcePath       = join-path $applicationPath &quot;_<span style="color: #8b0000">PublishedWebsites</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 13:       DestinationPath  = &quot;<span style="color: #8b0000">C:\inetpub\wwwroot</span>&quot; 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 14:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 15: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 16:     xWebsite DefaultSite
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 17:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 18:        Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 19:        Name            = &quot;<span style="color: #8b0000">Default Web Site</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 20:        State           = &quot;<span style="color: #8b0000">Stopped</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 21:        PhysicalPath    = &quot;<span style="color: #8b0000">C:\inetpub\wwwroot</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 22:        DependsOn       = &quot;<span style="color: #8b0000">[File]CopyDeploymentBits</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 23:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 24: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 25:     xWebsite NewWebsite
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 26:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 27:        Ensure          = &quot;<span style="color: #8b0000">Present</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 28:        Name            = &quot;<span style="color: #8b0000">BlogDemo</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 29:        State           = &quot;<span style="color: #8b0000">Started</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 30:        PhysicalPath    = &quot;<span style="color: #8b0000">c:\inetpub\wwwroot\BlogDemo</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 31:        DependsOn       = &quot;<span style="color: #8b0000">[xWebsite]DefaultSite</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 32:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 33:   }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><p> 34: }</p><p> 35: FileCopy</p></pre></pre>

<p>DSC has many parts. More information on DSC can be found by looking at the <a href="https://vsardevops.codeplex.com/releases/view/132181">ALM Rangers guidance</a> which was just released (I am on this ALM Rangers team).</p>

<p>The first thing is, “how do I know what to put in here – what are my options?” I’m glad you asked! The components used here are either the built-in File module or the xWebAdministration module available for download and noted above. The PowerShell DSC gallery has very good documentation and source code! In order to use these modules they need to be imported, hence the Import-Dsc statement in Line 3.</p>

<p>Once you have this statement you have to set which node (server) to apply this configuration to (i.e. you can apply a configuration to more than one server at a time but for clarity sake we will not do that and will configure each server separately. Localhost here refers to whatever server this DSC is deployed.</p>

<p>So, what does “File” do? On line 7 put your cursor on the word “File” and press Ctrl + spacebar. You end up with the tooltip shown in Figure 12 (the CopyDeploymentBits statement is a label that identifies the section as you can have multiple configuration sections).</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7673.image_736BAF2D.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7673.image_5F00_736BAF2D.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3056.image_thumb_6C4C72B5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3056.image_5F00_thumb_5F00_6C4C72B5.png" width="244" height="117" /></a></p>

<p>Figure 12 – File DSC tooltip</p>

<p>In many cases these values are straightforward. The benefit of this list is it provides you with the allowed array values. For this walkthrough the values are easy to understand.&#160; We want to ensure that a directory (Type) is present (Ensure). The source of the files is $applicationPath (this is a built-in parameter passed by RM which points to C:\Windows\DtlDownload\[Component Name]) plus the _publishedWebsites folder. The destination is the deployment path (note that this can be completely arbitrary but again this is for simplicity sake) and we want to take all of the contents recursively.</p>

<p>This file is so clear that it can be passed from a development team to an operations team and there should be a common understanding of what is happening.</p>

<p align="left">The next section stops the default website since our plan is to deploy our website to port 80 which the default website runs on. This is fairly straightforward but we’ve added another line down at the bottom: DependsOn. This tells DSC not to execute this section until the CopyDeploymentBits section has executed successfully. In this way we can chain a series of actions together to run in a specific order.</p>

<p align="left">Finally the last section creates a new website and starts it but only if the default website was first stopped (there are options to deploy it to another port).</p>

<p align="left">The last line actually triggers the DSC to create a Managed Object Framework file which causes the configuration to be executed.</p>

<p align="left">Save this file as DeploymentScript1.ps1 and add it to the DeploymentScripts project in Visual Studio (and make sure that the properties on the file are such that the copy output is “Copy if Newer” so it is deployed as part of our build) and check it in.</p>

<h2 align="left">Create the build</h2>

<p align="left">The build is very straightforward. Unlike previous versions of Release Management, the Release Management Service executes deployments based on triggers from the build service itself, not the build template so no special templates are needed now.</p>

<p align="left">Create a new build using any template (I’m using the Default Template with <em>no</em> changes to the build). Because I have the solution currently opened in Visual Studio it is automatically pulling the correct solution. Save the build definition as BlogDemo OnDemand (you could trigger this as a CI build if desired). Save the build definition and jump back into the Release Management client.</p>

<h2>Configuring the Release Process</h2>

<p>The first part of configuring a release process which is going to use DSC and VSO is to tell the Release Management tool where the build is located. To do this we’re going to add the most basic component. Head over to the Configure Apps &gt; Components page and click New vNext. Without making any other changes, select Builds with Application on the Sources tab as shown in Figure 11 and put a single backslash in the [Build Drop Location] field (also shown in Figure 13).</p>

<p>Note that it is critical you leave the name as “New Component 1”. If you’ll remember from the DSC script, this is part of the path that our application is copied to as part of the deployment.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8750.image_39E89F36.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8750.image_5F00_39E89F36.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7103.image_thumb_6E88FB71.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7103.image_5F00_thumb_5F00_6E88FB71.png" width="244" height="177" /></a></p>

<p>Figure 13 – Build location setting</p>

<p>Save and close the new component. Now it’s time to configure the actual release process. Go to the Configure Apps &gt; vNext Release Templates page and click New. This opens the properties page for the designer as shown in Figure 14.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/1731.image_6E1CC87C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/1731.image_5F00_6E1CC87C.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3480.image_thumb_5BD401BA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3480.image_5F00_thumb_5F00_5BD401BA.png" width="244" height="186" /></a></p>

<p>Figure 14 – Release Template properties page</p>

<p>Rename the release process, select the release path that you created earlier and select the team project and build definition. Then check the “Can Trigger a release” checkbox and click Create.</p>

<p>You’ll start out with a blank slate with tabs defined for the number of environments you created in your release process as shown in Figure 15.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8203.image_77788DB0.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8203.image_5F00_77788DB0.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0763.image_thumb_37427436.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0763.image_5F00_thumb_5F00_37427436.png" width="244" height="177" /></a></p>

<p>Figure 15 – Blank release process</p>

<p>The first thing to do is add the component you created previously. Right-click the Components node and select Add and then choose New Component 1. Because we are using PowerShell DSC drag a Deploy Using PS/DSC action to the Deployment Sequence and click the double arrow in the upper right to expand the activity.</p>

<p>Select the server from the ServerName field. Enter the UserName and Password of an account which has administrative access to the server. Select New Component 1 from the ComponentName dropdown. Finally, in the PSScriptPath field, enter DeploymentScript1.ps1.</p>

<p>To copy the configuration to the Test and Production environments, right-click the deployment tab (shown in Figure 16) and select Copy Deployment Sequence. Then right-click the Test and eventually Production tabs and select Paste Deployment Sequence. Change the ServerName field to the correct server and you’re done!</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5852.image_24F9AD74.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5852.image_5F00_24F9AD74.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8117.image_thumb_2BACB6F7.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8117.image_5F00_thumb_5F00_2BACB6F7.png" width="244" height="84" /></a></p>

<p>Figure 16 – Copying the deployment sequence</p>

<p>At this point you can trigger a build in Visual Studio and watch the application deploy. </p>

<p>In the next post in the series I’ll look at configuring a completely clean server and using more variables so as to avoid hard-coding entries in the DSC file.<font color="#333333" face="Segoe UI"></font></p>





<p><font color="#260859" face="Segoe UI Semibold"></font></p>]]></content:encoded>
    </item>
    <item>
      <title>Azure Mobile Services prompts you for a username and password</title>
      <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/azure-mobile-services-prompts-you-for-a-username-and-password</link>
      <pubDate>Thu, 23 Oct 2014 13:16:14 GMT</pubDate>
      <dc:creator><![CDATA[Jeff Levinson (p)]]></dc:creator>
      <guid
        isPermaLink="false">http://qa.msdn.wdslab.com/musings_on_alm_and_software_development_processes/2014/10/23/azure-mobile-services-prompts-you-for-a-username-and-password/</guid>
      <description><![CDATA[So you’ve built and deployed your first Azure Mobile Service. Awesome! then you get prompted for a...]]></description>
      <content:encoded><![CDATA[<p>So you’ve built and deployed your first Azure Mobile Service. Awesome! then you get prompted for a username and password and you can’t use your new mobile service! The good news is that this is by design and being that it is by design, there is an appropriate and easy way to deal with it. The reason for it is security pure and simple and the information needed to get past it is available to you.</p>  <p>To start with, you have a mobile service in Azure that looks like the following:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2642.image_51300CB9.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2642.image_5F00_51300CB9.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5488.image_thumb_1ECC393A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5488.image_5F00_thumb_5F00_1ECC393A.png" width="244" height="172" /></a> </p>  <p>Figure 1: Mobile Service Dashboard</p>  <p>Clicking the highlighted link takes you to this page:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2063.image_5A8BD1ED.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2063.image_5F00_5A8BD1ED.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/1581.image_thumb_4C4D58FD.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/1581.image_5F00_thumb_5F00_4C4D58FD.png" width="244" height="161" /></a> </p>  <p>Figure 2: Mobile Service entry page</p>  <p>Clicking the Try it out button brings you to the username/password dialog. Looking back at the mobile services dashboard you’ll see the Manage Keys button at the bottom of the screen as shown in Figure 3.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2570.image_080CF1B1.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2570.image_5F00_080CF1B1.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5226.image_thumb_47D6D836.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5226.image_5F00_thumb_5F00_47D6D836.png" width="244" height="74" /></a> </p>  <p>Figure 3: Manage Keys</p>  <p>Click the button and then copy either the primary or secondary key. Now, click the Try me button and when the username/password dialog is displayed, paste the key into the password field (leave the username field blank) and click OK. And voila you get to the service as shown in Figure 4.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8053.image_55A91E31.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8053.image_5F00_55A91E31.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0523.image_thumb_7C773471.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0523.image_5F00_thumb_5F00_7C773471.png" width="244" height="205" /></a> </p>  <p>Figure 4: The working mobile service</p>]]></content:encoded>
    </item>
    <item>
      <title>PowerShell DSC for DevOps and ALM v1.0 released</title>
      <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/powershell-dsc-for-devops-and-alm-v1-0-released</link>
      <pubDate>Thu, 16 Oct 2014 20:30:13 GMT</pubDate>
      <dc:creator><![CDATA[Jeff Levinson (p)]]></dc:creator>
      <guid
        isPermaLink="false">http://qa.msdn.wdslab.com/musings_on_alm_and_software_development_processes/2014/10/16/powershell-dsc-for-devops-and-alm-v1-0-released/</guid>
      <description><![CDATA[I’m excited to add to the fanfare that the first set of ALM Ranger Guidance for PowerShell DSC has...]]></description>
      <content:encoded><![CDATA[<p>I’m excited to add to the fanfare that the first set of ALM Ranger Guidance for PowerShell DSC has been released (full details can be found on Willy’s blog here: <a title="http://blogs.msdn.com/b/willy-peter_schaub/archive/2014/10/16/powershell-desired-state-configuration-for-devops-and-alm-practitioners-v1.aspx" href="http://blogs.msdn.com/b/willy-peter_schaub/archive/2014/10/16/powershell-desired-state-configuration-for-devops-and-alm-practitioners-v1.aspx">http://blogs.msdn.com/b/willy-peter_schaub/archive/2014/10/16/powershell-desired-state-configuration-for-devops-and-alm-practitioners-v1.aspx</a>). I have been a part of other Ranger projects before but this one was different for a number of reasons and I wanted to talk about it and how it applies to DevOps in general.</p>  <p>In virtually all Ranger projects, experts from Microsoft, Microsoft Most Valuable Professionals and various other experts in the industry are brought in to help with a project (it is truly remarkable as we all work on these projects in our spare time). We engage with the product team(s) as needed when we need technical guidance and someone from the product team is almost always chosen as the Product Owner. This was different. Desired State Configuration (DSC) is relatively new. The guidance out there is still in development. Many blog posts, books and articles have been written about it but a lot of the details and plumbing were either missing or incomplete. While PowerShell is ubiquitous when it comes to managing Windows Servers and even Azure, its application with DSC is very new.</p>  <p>But Rangers aren’t shy – a bunch of us with PowerShell experience, ALM and Release Management and Operations experience committed to work on the project even though we knew relatively little about DSC. However, we’re a committed bunch when we put our minds to it – I’m proud to be a part of a group who’s vocabulary does not include the word “quit”. We all had to learn a lot and fast. The Product Team, lead by Keith Bankston as our PO spent time educating us, pointing us to all of the material available and really helping us over every bump we ran into – and we ran into a lot of them. We spent several weeks ramping up on the technology and then we started asking questions.</p>  <p>One thing I can’t emphasize enough is that while DSC isn’t particularly hard – that’s one of the beauties of it – the process has to be understood and in many ways that is way, way harder than the technology which we all picked up relatively easily. But from a process perspective we started asking questions and we came up with some really good answers so that you, the consumer of DSC, don’t have to think about quite as much as we did.</p>  <h1>Is DSC absolute?</h1>  <p>When we think of the word “State” in computer science we think of an absolute. Here is how it is defined by <a href="http://en.wikipedia.org/wiki/State_(computer_science)" target="_blank">Wikipedia</a>:</p>  <p> “…the state of a digital logic circuit or computer program is a technical term for all of the stored information, at a given instant in time, to which the circuit or program has access.”</p>  <p>There’s no room for fudging here. However, that’s not quite how “State” is defined when it comes to DSC because there are two instances of use in DSC.</p>  <h2>Instance 1: A resource reserved for a single use exclusively</h2>  <p>In this scenario, the individual configuring the system is the only individual needing a resource to be in a given state. An example of this is a server that is dedicated to support only a single application.</p>  <h2>Instance 2: A shared resource</h2>  <p>In this scenario one or more individuals may need the system configured for their own use but they are doing it on the same system. An example of this is a web server hosting two different applications.</p>  <p>The Ranger guidance talks about minimum and absolute configurations. But the question of minimum configuration led to a question that I asked during the development of the guidance – what happens when there are two different configuration files which target a single server? The answer: this situation is not possible. A single target machine can only pull its configuration (or have a configuration pushed to it) by a single machine. On the source machine, only a single configuration can apply to a target machine. This leads to the second important item.</p>  <h1>Version control your configuration scripts</h1>  <p>We mention this quite prominently in the guidance. However, the paragraph above describes a scenario where multiple people are accessing the same configuration file and possibly making changes to the same configuration settings. My first thought was, “well, how do you stop someone from changing your configuration?” Keith had the best answer that I’ve ever heard: “The people making changes to the configuration <em>have to talk with each other!”</em> Well, how often does that happen? It’s going to have to happen – and even better, the configuration is also a very easy way to communicate with the operations team.</p>  <p>Take advantage of DSC as means to communicate with other people using a server and the operations team. And maybe the operations team is the group that owns the configuration and helps facilitate communication with all teams using a given server.</p>  <p>I hope you enjoy the guidance and I’m happy to have been a part of this team – it was great, great people, great technology and a great environment.</p>]]></content:encoded>
    </item>
    <item>
      <title>Outputting WADL for API Management from a Web API Service</title>
      <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/outputting-wadl-for-api-management-from-a-web-api-service</link>
      <pubDate>Wed, 17 Sep 2014 08:22:17 GMT</pubDate>
      <dc:creator><![CDATA[Jeff Levinson (p)]]></dc:creator>
      <guid
        isPermaLink="false">http://qa.msdn.wdslab.com/musings_on_alm_and_software_development_processes/2014/09/17/outputting-wadl-for-api-management-from-a-web-api-service/</guid>
      <description><![CDATA[I created a new set of services in Azure Mobile Services (this is specific to AMS) and tried to...]]></description>
      <content:encoded><![CDATA[<p>I created a new set of services in Azure Mobile Services (this is specific to AMS) and tried to consume them with API Management. In order to import the API however, you have to have a <a href="http://www.w3.org/Submission/wadl/">WADL</a> or <a href="http://swagger.io/">Swagger</a> document that describes the API. Being new to AMS applications I wasn’t sure how to do it. Along came some help from the API Management product team. They provided me a very simple file that output WADL automatically. Hopefully this will help make life easier for everyone (note that for Web API or Azure Websites you can simply add one of the available WADL or Swagger packages from NuGet that are available to you).</p>  <pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System.Collections.Generic;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System.Linq;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System.Net;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System.Net.Http;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System.Web.Http;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> Microsoft.WindowsAzure.Mobile.Service;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System.Xml;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System.Web.UI.WebControls;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System.IO;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System.Text;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">using</span> System.Web.Http.Description;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">namespace</span> DataService.Controllers
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">{
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">class</span> XmlTypeExtensions
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        <span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">readonly</span> Dictionary&lt;Type, <span style="color: #0000ff">string</span>&gt; TypeMappings = <span style="color: #0000ff">new</span> Dictionary&lt;Type, <span style="color: #0000ff">string</span>&gt;()     
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">     {                 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        {<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">string</span>), &quot;<span style="color: #8b0000">string</span>&quot; },
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        {<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">bool</span>), &quot;<span style="color: #8b0000">boolean</span>&quot; },
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        {<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">decimal</span>), &quot;<span style="color: #8b0000">decimal</span>&quot; },
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        {<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">float</span>), &quot;<span style="color: #8b0000">float</span>&quot; },
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        {<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">double</span>), &quot;<span style="color: #8b0000">double</span>&quot; },
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        {<span style="color: #0000ff">typeof</span>(<span style="color: #0000ff">int</span>), &quot;<span style="color: #8b0000">int</span>&quot; },
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        {<span style="color: #0000ff">typeof</span>(DateTime), &quot;<span style="color: #8b0000">datetime</span>&quot; },
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        {<span style="color: #0000ff">typeof</span>(Guid), &quot;<span style="color: #8b0000">guid</span>&quot; }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">     };
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">string</span> ToXmlTypeString(<span style="color: #0000ff">this</span> Type type)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            <span style="color: #0000ff">string</span> typeString;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            <span style="color: #0000ff">if</span> (TypeMappings.TryGetValue(type, <span style="color: #0000ff">out</span> typeString))
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                <span style="color: #0000ff">return</span> typeString;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            <span style="color: #0000ff">return</span> <span style="color: #0000ff">null</span>;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    [AuthorizeLevel(Microsoft.WindowsAzure.Mobile.Service.Security.AuthorizationLevel.Anonymous)]
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> WadlController : ApiController
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        <span style="color: #0000ff">public</span> ApiServices Services { <span style="color: #0000ff">get</span>; <span style="color: #0000ff">set</span>; }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        <span style="color: #008000">// GET api/Wadl</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        <span style="color: #0000ff">public</span> HttpResponseMessage Get()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            StringBuilder sb = <span style="color: #0000ff">new</span> StringBuilder();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            <span style="color: #0000ff">using</span> (XmlWriter xw = XmlWriter.Create(<span style="color: #0000ff">new</span> StringWriter(sb)))
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                xw.WriteStartElement(&quot;<span style="color: #8b0000">application</span>&quot;, &quot;<span style="color: #8b0000">http://wadl.dev.java.net/2009/02</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                xw.WriteStartElement(&quot;<span style="color: #8b0000">resources</span>&quot;, &quot;<span style="color: #8b0000">http://wadl.dev.java.net/2009/02</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                xw.WriteAttributeString(&quot;<span style="color: #8b0000">base</span>&quot;, &quot;<span style="color: #8b0000">https://</span>&quot; + Services.Settings.Name + &quot;<span style="color: #8b0000">.azure-mobile.net</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                var apiDescriptions = Configuration.Services.GetApiExplorer().ApiDescriptions;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                <span style="color: #0000ff">foreach</span> (System.Web.Http.Description.ApiDescription api <span style="color: #0000ff">in</span> apiDescriptions)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteStartElement(&quot;<span style="color: #8b0000">resource</span>&quot;, &quot;<span style="color: #8b0000">http://wadl.dev.java.net/2009/02</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteAttributeString(&quot;<span style="color: #8b0000">path</span>&quot;, api.RelativePath);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteStartElement(&quot;<span style="color: #8b0000">doc</span>&quot;, &quot;<span style="color: #8b0000">http://wadl.dev.java.net/2009/02</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteAttributeString(&quot;<span style="color: #8b0000">title</span>&quot;, api.Documentation);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteEndElement();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteStartElement(&quot;<span style="color: #8b0000">method</span>&quot;, &quot;<span style="color: #8b0000">http://wadl.dev.java.net/2009/02</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteAttributeString(&quot;<span style="color: #8b0000">name</span>&quot;, api.HttpMethod.Method);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteStartElement(&quot;<span style="color: #8b0000">request</span>&quot;, &quot;<span style="color: #8b0000">http://wadl.dev.java.net/2009/02</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    <span style="color: #0000ff">foreach</span> (var param <span style="color: #0000ff">in</span> api.ParameterDescriptions)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                        xw.WriteStartElement(&quot;<span style="color: #8b0000">param</span>&quot;, &quot;<span style="color: #8b0000">http://wadl.dev.java.net/2009/02</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                        xw.WriteAttributeString(&quot;<span style="color: #8b0000">name</span>&quot;, param.Name);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                        xw.WriteAttributeString(&quot;<span style="color: #8b0000">style</span>&quot;, &quot;<span style="color: #8b0000">template</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                        xw.WriteStartAttribute(&quot;<span style="color: #8b0000">type</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                        xw.WriteQualifiedName(param.ParameterDescriptor.ParameterType.ToXmlTypeString() ?? &quot;<span style="color: #8b0000">string</span>&quot;, &quot;<span style="color: #8b0000">http://www.w3.org/2001/XMLSchema</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                        xw.WriteEndAttribute();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                        xw.WriteAttributeString(&quot;<span style="color: #8b0000">required</span>&quot;, &quot;<span style="color: #8b0000">true</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                        xw.WriteEndElement();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    var model = Configuration.GetHelpPageApiModel(api.GetFriendlyId());
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteEndElement(); <span style="color: #008000">// request</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteEndElement(); <span style="color: #008000">// method</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                    xw.WriteEndElement(); <span style="color: #008000">//resource</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                xw.WriteEndElement(); <span style="color: #008000">//resources</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">                xw.WriteEndElement(); <span style="color: #008000">//application</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            HttpResponseMessage response = Request.CreateResponse();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            response.Content = <span style="color: #0000ff">new</span> StringContent(sb.ToString(), UTF8Encoding.Unicode, &quot;<span style="color: #8b0000">text/xml</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            <span style="color: #0000ff">return</span> response;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">}</pre></pre>

<p>Add this controller to your Web API application and your done. At this point you can import your API into API Management.</p>]]></content:encoded>
    </item>
    <item>
      <title>CORS and Azure API Management</title>
      <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/cors-and-azure-api-management</link>
      <pubDate>Mon, 15 Sep 2014 19:13:21 GMT</pubDate>
      <dc:creator><![CDATA[Jeff Levinson (p)]]></dc:creator>
      <guid
        isPermaLink="false">http://qa.msdn.wdslab.com/musings_on_alm_and_software_development_processes/2014/09/15/cors-and-azure-api-management/</guid>
      <description><![CDATA[I was working on publishing an API via Azure Mobile Services and I wanted to manage it with API...]]></description>
      <content:encoded><![CDATA[<p>I was working on publishing an API via Azure Mobile Services and I wanted to manage it with API Management. I got everything published and from within the API Management development console everything worked fine. Then I wrote an application to consume the API and that’s where I ran into a problem. It took hours of searching to find the solution so I hope this helps someone else avoid the problem.</p>  <p>CORS stands for Cross-Origin-Resource-Sharing (detailed information can be found at the W3C <a href="http://www.w3.org/TR/cors/">here</a>). I’ll give it to you in a nutshell here. It is a security mechanism to ensure that data designed to be used for a domain stays in that domain and can’t be used outside of it. In other words it’s a security mechanism. In addition, whether or not you are allowed to access the data is accomplished by a <em>response</em>, not request, header. That means that you cannot make a request to a server for it to serve up data that is protected against CORS. It is the source server that must allow a CORS request.</p>  <p>So, back to the story. I built a small website that retrieved the data from API Management and continued to get a CORS error. I tried everything on the client I could to make it work. I finally found the W3C documentation which pointed me to the server. I checked API Management and I couldn’t find anything on CORS… until I found the Policy tab.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3583.image_78CB80E2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3583.image_5F00_78CB80E2.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8664.image_thumb_2FA865DA.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8664.image_5F00_thumb_5F00_2FA865DA.png" width="244" height="115" /></a></p>  <p>Clicking the Policies tab on the left hand side (highlighted) brings us to this screen:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2248.image_69502126.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2248.image_5F00_69502126.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5468.image_thumb_2B569068.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5468.image_5F00_thumb_5F00_2B569068.png" width="244" height="205" /></a></p>  <p>On the Policies tab, select the Product, API and specific call. You’ll notice on the right side the CORS policy (as well as others that I would urge you to explore). Put your cursor after the &lt;inbound&gt; tag and above the &lt;base/&gt; tag then click the CORS policy (note that this is an inbound request because the client <em>makes a request of the server</em> and the server sends the response saying yes you can have it). There are some other default CORS options but the way I configured it was to allow requests from anywhere because it was simply a demonstration API.</p>  <p>This should get you past your CORS problem.</p>]]></content:encoded>
    </item>
    <item>
      <title>Integrating an MVC application with Azure Active Directory (Visual Studio 2013)… and being able to deploy it</title>
      <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/integrating-an-mvc-application-with-azure-active-directory-visual-studio-2013-and-being-able-to-deploy-it</link>
      <pubDate>Tue, 09 Sep 2014 20:05:18 GMT</pubDate>
      <dc:creator><![CDATA[Jeff Levinson (p)]]></dc:creator>
      <guid
        isPermaLink="false">http://qa.msdn.wdslab.com/musings_on_alm_and_software_development_processes/2014/09/09/integrating-an-mvc-application-with-azure-active-directory-visual-studio-2013-and-being-able-to-deploy-it/</guid>
      <description><![CDATA[Things have changed a little between Visual Studio 2012 and Visual Studio 2013. I had not used this...]]></description>
      <content:encoded><![CDATA[<p>Things have changed a little between Visual Studio 2012 and Visual Studio 2013. I had not used this capability in 2012 and when I started trying to do this, I found out that there was little to no documentation on how to do it or that it was all out of date. Hence this post. Hopefully you will find it useful and I’ll follow up with another post on how to convert an existing MVC application from forms authentication into being able to use AAD.</p>  <h1>Creating the basic MVC application</h1>  <ul>   <li>Open Visual Studio and select File &gt; New Project </li>    <li>Select Web &gt; ASP.NET Web Application </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7357.image_60DDCF08.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7357.image_5F00_60DDCF08.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0027.image_thumb_4A1E877F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0027.image_5F00_thumb_5F00_4A1E877F.png" width="244" height="170" /></a> </p>  <ul>   <li>Rename it something unique and click OK </li>    <li>Click Change Authentication </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3247.image_3BE00E8F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3247.image_5F00_3BE00E8F.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4336.image_thumb_2C40037E.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4336.image_5F00_thumb_5F00_2C40037E.png" width="244" height="183" /></a> </p>  <ul>   <li>Select Organizational Accounts </li>    <li>Enter your Azure domain name </li>    <li>You can either leave the Access level at Single Sign On or change it as desired – in this case I changed it to Single Sign On, Read directory data </li>    <li>Expand the More Options and make sure the App ID URI is filled in appropriately – if it is, don’t make any changes to it      <ul>       <li>If it is not filled in, enter “https://[domain as listed in the domain field]/[application name] </li>     </ul>   </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5228.image_3E1C974B.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5228.image_5F00_3E1C974B.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/6712.image_thumb_198B09C7.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/6712.image_5F00_thumb_5F00_198B09C7.png" width="244" height="143" /></a> </p>  <ul>   <li>Click OK </li>    <li>Make sure Host in the cloud is checked and Website is selected in the drop-down </li>    <li>Click OK </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5734.image_203E134A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5734.image_5F00_203E134A.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8484.image_thumb_470C298A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8484.image_5F00_thumb_5F00_470C298A.png" width="244" height="186" /></a> </p>  <ul>   <li>On the Configure Azure Website dialog, leave the defaults as is (or change the server location if necessary) and click OK      <ul>       <li>Note that I’m walking through the default settings – this isn’t sufficient as you’ll see later on </li>     </ul>   </li> </ul>  <p>Very shortly the website will be provisioned (but not published).</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4572.image_4295A8C3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4572.image_5F00_4295A8C3.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8308.image_thumb_025F8F49.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8308.image_5F00_thumb_5F00_025F8F49.png" width="244" height="169" /></a> </p>  <p>Everything’s done – like every good developer we want to run what we just created to get that sense of satisfaction so let’s do that.</p>  <h2>Running the default web application</h2>  <p>Let’s see how well this works:</p>  <ul>   <li>Press F5 </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4111.image_7DE90E81.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4111.image_5F00_7DE90E81.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/6747.image_thumb_28C17294.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/6747.image_5F00_thumb_5F00_28C17294.png" width="244" height="155" /></a> </p>  <ul>   <li>A certificate warning page is displayed because by default it puts SSL in place and it uses a self-signed certificate. No problem here, click Continue to this website (not recommended). </li>    <li>Next the Sign in to Azure Active Directory page is displayed – so far so good! </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7762.image_4F8F88D4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7762.image_5F00_4F8F88D4.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7271.image_thumb_2AFDFB50.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7271.image_5F00_thumb_5F00_2AFDFB50.png" width="244" height="155" /></a> </p>  <ul>   <li>Click the user to sign in as (if you don’t have an AD user (versus your Microsoft credentials) skip this part – we’ll add some credentials in a little bit). </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4532.image_7FB96448.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4532.image_5F00_7FB96448.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0334.image_thumb_066C6DCC.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0334.image_5F00_thumb_5F00_066C6DCC.png" width="244" height="155" /></a> </p>  <ul>   <li>As a side note, if you do enter your Microsoft credentials you’ll get this little gem (we’ll come back and address this in a bit): </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2084.image_7F4D3153.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2084.image_5F00_7F4D3153.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3173.image_thumb_61DAE047.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3173.image_5F00_thumb_5F00_61DAE047.png" width="244" height="131" /></a> </p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <p></p>  <ul>   <li>Enter your username and password and click Sign in </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8875.image_73B77414.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8875.image_5F00_73B77414.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/1732.image_thumb_76602FC5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/1732.image_5F00_thumb_5F00_76602FC5.png" width="244" height="155" /></a> </p>  <ul>   <li>Lo and behold we have access to our application </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7612.image_083CC393.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7612.image_5F00_083CC393.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/1348.image_thumb_23E14F89.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/1348.image_5F00_thumb_5F00_23E14F89.png" width="244" height="155" /></a> </p>  <p>Sweet! Now let’s publish it… </p>  <ul>   <li>Right-click the project name in Solution Explorer and select Publish </li>    <li>Without making any changes (nothing you can do can change the outcome at this point) click Publish </li>    <li>After the application publishes it will automatically launch. Crossing our fingers at this point, closing our eyes and praying a little bit we open them up and… </li> </ul>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4503.image_1CC21311.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4503.image_5F00_1CC21311.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7230.image_thumb_38669F07.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7230.image_5F00_thumb_5F00_38669F07.png" width="244" height="155" /></a> </p>  <p>DOH!</p>  <p>This isn’t particularly helpful so let’s modify the web.config to get some additional information. Adding the section indicated and re-running it (which by the way you don’t have to republish to do this – you can simply edit the web.config on the server by looking in Server Explorer as shown here:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7723.image_5F34B547.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7723.image_5F00_5F34B547.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8132.image_thumb_50F63C57.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8132.image_5F00_thumb_5F00_50F63C57.png" width="127" height="244" /></a> </p>  <p>Double-click the web.config file to open it and you’ll note that it says [Remote] in the document tab. After adding the following code:</p>  <pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">&lt;customErrors Mode=&quot;<span style="color: #8b0000">Off</span>&quot; /&gt;</pre></pre>

<p>Save the web.config, right-click on the website in Solution Explorer and click Browse. Now we get the following back (instead of a screenshot of an entire stack trace, I’m just going to show the first line which is the only important line here):</p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">[SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 52 - Unable to locate a Local Database Runtime installation. Verify that SQL Server Express is properly installed and that the Local Database Runtime feature is enabled.)]
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre></pre>

<p></p>

<p></p>

<p></p>

<p>Um, huh? What database? We didn’t add a database and the default MVC application doesn’t have anything that uses a database. Let’s check out the web.config and see what’s accessing a database.</p>

<p>Looking at the web.config we see the following entry:</p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  <span style="color: #0000ff">&lt;</span><span style="color: #800000">connectionStrings</span><span style="color: #0000ff">&gt;</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    <span style="color: #0000ff">&lt;</span><span style="color: #800000">add</span> <span style="color: #ff0000">name</span>=<span style="color: #0000ff">&quot;DefaultConnection&quot;</span> <span style="color: #ff0000">connectionString</span>=<span style="color: #0000ff">&quot;Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-ADIntegrationDemo-20140909062518.mdf;Initial Catalog=aspnet-ADIntegrationDemo-20140909062518;Integrated Security=True&quot;</span> <span style="color: #ff0000">providerName</span>=<span style="color: #0000ff">&quot;System.Data.SqlClient&quot;</span> <span style="color: #0000ff">/&gt;</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  <span style="color: #0000ff">&lt;/</span><span style="color: #800000">connectionStrings</span><span style="color: #0000ff">&gt;</span></pre></pre>

<p>What’s this about? Well, if you’ve written MVC applications you’ll know this is where VS stores data related to ASP.Net related authentication. Well, this is the same type of situation but different.</p>

<p>What the application is trying to do is to grab two specific pieces of information so it can authenticate the client using SAML assertions against Azure AD. The problem is that once you deploy it to the web, this database is not accessible anymore. So how do you fix it and what goes in the database.</p>

<h2>Fixing the problem</h2>

<p>In order to fix the problem we have to look at the local database. To do that, do the following:</p>

<ul>
  <li>In Server Explorer, expand the Data Connections node and you should already see a connection to the application’s database as shown here: </li>
</ul>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/6562.image_25B1A550.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/6562.image_5F00_25B1A550.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4442.image_thumb_213B2489.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4442.image_5F00_thumb_5F00_213B2489.png" width="132" height="244" /></a> </p>

<ul>
  <li>If it doesn’t exist, add it as follows: 
    <ul>
      <li>Right-click Data Connections and select Add Connection </li>

      <li>Change the data source to Microsoft SQL Server Database File </li>

      <li>Browse to the App_Data folder and select the mdf file there </li>

      <li>Click OK </li>
    </ul>
  </li>

  <li>Expanding the table nodes we find a very simple schema </li>

  <li>The important tables are the IssuingAuthorityKeys and the Tenants table. Right-click each table and select Show Data </li>
</ul>

<p>Each table has a single column and a single row. These tables need to be moved to a database accessible to the ASP.Net MVC application running in Azure. For our purposes we’ll use a SQL Database. For simplicities sake I’ve created the SQL statements needed to be executed against a SQL database. Replace the two insert statements with the values found in each of the respective tables as shown (for example):</p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=SET&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">SET</a> ANSI_NULLS <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=ON&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">ON</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=GO&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">GO</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=SET&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">SET</a> QUOTED_IDENTIFIER <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=ON&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">ON</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=GO&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">GO</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=CREATE&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">CREATE</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=TABLE&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">TABLE</a> [dbo].[__MigrationHistory] (
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    [MigrationId]    <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NVARCHAR&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NVARCHAR</a> (150)  <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NOT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NOT</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NULL&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NULL</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=PRIMARY&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">PRIMARY</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=KEY&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">KEY</a>,
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    [ContextKey]     <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NVARCHAR&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NVARCHAR</a> (300)  <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NOT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NOT</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NULL&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NULL</a>,
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    [Model]          <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=VARBINARY&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">VARBINARY</a> (<a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=MAX&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">MAX</a>) <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NOT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NOT</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NULL&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NULL</a>,
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    [ProductVersion] <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NVARCHAR&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NVARCHAR</a> (32)   <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NOT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NOT</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NULL&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NULL</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=GO&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">GO</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=CREATE&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">CREATE</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=TABLE&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">TABLE</a> [dbo].[IssuingAuthorityKeys] (
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    [Id] <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NVARCHAR&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NVARCHAR</a> (128) <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=PRIMARY&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">PRIMARY</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=KEY&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">KEY</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NOT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NOT</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NULL&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NULL</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=GO&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">GO</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=CREATE&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">CREATE</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=TABLE&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">TABLE</a> [dbo].[Tenants] (
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    [Id] <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NVARCHAR&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NVARCHAR</a> (128) <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NOT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NOT</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=NULL&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">NULL</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=PRIMARY&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">PRIMARY</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=KEY&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">KEY</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=GO&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">GO</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=INSERT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">INSERT</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=INTO&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">INTO</a> [dbo].[IssuingAuthorityKeys]
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00">           ([Id])
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00">     <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=VALUES&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">VALUES</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00">           ('<span style="color: #8b0000">92B88C3DD981BF1EBCB244FCFA63C007706C79E0</span>')
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=GO&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">GO</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=INSERT&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">INSERT</a> <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=INTO&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">INTO</a> [dbo].Tenants
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00">           ([Id])
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00">     <a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=VALUES&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">VALUES</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00">           ('<span style="color: #8b0000">67c3a3d5-b264-4328-ade6-7a7b81136117</span>')
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><a style="color: #0000ff" href="http://search.microsoft.com/default.asp?so=RECCNT&amp;siteid=us%2Fdev&amp;p=1&amp;nq=NEW&amp;qu=GO&amp;IntlSearch=&amp;boolean=PHRASE&amp;ig=01&amp;i=09&amp;i=99">GO</a>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre></pre>

<ul>
  <li>If you don’t have an existing SQL database, create one in the Azure Management Portal or Server Explorer</li>

  <li>Select the SQL Databases node and highlight the appropriate database (in my example I’m using a customer_demonstrator database) and click Manage at the bottom of the page</li>
</ul>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0654.image_0766EE5A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0654.image_5F00_0766EE5A.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4848.image_thumb_0A0FAA0B.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4848.image_5F00_thumb_5F00_0A0FAA0B.png" width="244" height="143" /></a> </p>

<ul>
  <li>Provide the login credentials for the database and click Log On</li>
</ul>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5037.image_02F06D93.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5037.image_5F00_02F06D93.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5050.image_thumb_42BA5418.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5050.image_5F00_thumb_5F00_42BA5418.png" width="244" height="205" /></a> </p>

<p></p>

<ul>
  <li>Click New Query in the resulting window</li>
</ul>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7115.image_7E79ECCB.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7115.image_5F00_7E79ECCB.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3733.image_thumb_32AE1612.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3733.image_5F00_thumb_5F00_32AE1612.png" width="244" height="143" /></a> </p>

<ul>
  <li>Paste the script in the sql window and click run (after replacing the issuing authority key and tenants key)</li>
</ul>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5875.image_2B8ED99A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5875.image_5F00_2B8ED99A.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4807.image_thumb_47336590.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4807.image_5F00_thumb_5F00_47336590.png" width="244" height="143" /></a> </p>

<p>Now we have a table that holds the appropriate data needed by the application. Let’s try publishing the application once again. This time however we’re going to make a change to the connection string (make sure to grab the connection string for the database while you’re in the Azure portal).</p>

<ul>
  <li>On the Publish Web page, select the Settings tab:</li>
</ul>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/1780.image_40142918.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/1780.image_5F00_40142918.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5086.image_thumb_06911921.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5086.image_5F00_thumb_5F00_06911921.png" width="244" height="192" /></a> </p>

<ul>
  <li>Change the connection string using the connection string copied from the server (remember to put your password in)</li>
</ul>

<p>Now, I’ll save you the suspense – in our default configuration if we publish right now it will fail – there’s one last problem. By default SSL is not set up yet the configuration by default requires SSL (you’ll get the following error message: <i>ID1059: Cannot authenticate the user because the URL scheme is not https and requireSsl is set to true in the configuration, therefore the authentication cookie will not be sent. Change the URL scheme to https or set requireSsl to false on the cookieHandler element in configuration.</i>) </p>

<ul>
  <li>Click Close on the Publish Web dialog</li>

  <li>Open the web.config file and edit the following like:</li>
</ul>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">&lt;cookieHandler requireSsl=&quot;<span style="color: #8b0000">true</span>&quot; /&gt;</pre></pre>

<p></p>

<p></p>

<ul>
  <li>Change “true” to “false” – now publish the application</li>
</ul>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4747.image_5022F7CF.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4747.image_5F00_5022F7CF.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3264.image_thumb_61FF8B9C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3264.image_5F00_thumb_5F00_61FF8B9C.png" width="244" height="108" /></a> </p>

<p>Doh!!! We are just not having a lot of luck with this. What’s the problem now? Looking at the URL we can see that the callback for the logon takes us back to <a href="https://localhost:4430">https://localhost:4430</a> only we aren’t running on our local machine anymore – we want to go to <a href="http://adintegrationdemo.azurewebsites.com">http://adintegrationdemo.azurewebsites.com</a>. Let’s take a look at what was done in Azure under the covers. The fix is simple but it’s important to understand the end-to-end flow.</p>

<h2>Azure Active Directory</h2>

<p>Bet you thought we weren’t going to make it here…</p>

<p>When you first sign up for Azure, a default active directory instance is created for you. Navigating to the Azure Management Portal it looks like this:</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/1614.image_5D890AD5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/1614.image_5F00_5D890AD5.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8078.image_thumb_4B404413.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8078.image_5F00_thumb_5F00_4B404413.png" width="244" height="155" /></a> </p>

<p>Clicking the Default Directory takes you to this page:</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4380.image_720E5A53.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4380.image_5F00_720E5A53.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/1641.image_thumb_25D650A5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/1641.image_5F00_thumb_5F00_25D650A5.png" width="244" height="143" /></a> </p>

<p>Users can be added on the Users page (and obviously Groups on the groups page) but we’re going to focus on the Applications page. Clicking that we see the following (you’ll have only one application in there – the demo that we just put together most likely):</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8510.image_4CA466E5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8510.image_5F00_4CA466E5.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3323.image_thumb_16364594.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3323.image_5F00_thumb_5F00_16364594.png" width="244" height="143" /></a> </p>

<p>Drill into the appropriate application and click Configure. Update the Sign In URL and the Reply URL to the correct URL on Azure (like <a href="http://ADIntegrationDemo.azurewebsites.net">http://ADIntegrationDemo.azurewebsites.net</a>. Click Save. </p>

<p>In a new browser window, enter the URL. And lo and behold we have a working application!</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4237.image_2812D961.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4237.image_5F00_2812D961.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4101.image_thumb_583CB4D5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4101.image_5F00_thumb_5F00_583CB4D5.png" width="244" height="160" /></a> </p>

<p>Now, back to the problem we ran into very early on. For some reason (no, I don’t know why) when you try to log on with a Microsoft account the first time it returns null. If you try logging on a second time it works fine. I haven’t been able to puzzle through this but a simple change to the _LoginPartial.cshtml page – it doesn’t handle nulls at all. At the following to the top of the _LoginPartial page: </p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">@{
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    var user = &quot;<span style="color: #8b0000">Null User</span>&quot;;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    <span style="color: #0000ff">if</span> (!<span style="color: #0000ff">String</span>.IsNullOrEmpty(User.Identity.Name))
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        user = User.Identity.Name;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">}</pre></pre>

<p>And update the user action link to the following:</p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">@Html.ActionLink(user, &quot;<span style="color: #8b0000">UserProfile</span>&quot;, &quot;<span style="color: #8b0000">Home</span>&quot;, routeValues: null, htmlAttributes: null)</pre></pre>

<p>Republish the application and now it will handle any situation.</p>

<p>Enjoy!</p>]]></content:encoded>
    </item>
    <item>
      <title>Azure Event Hubs, Queues and Workers</title>
      <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/azure-event-hubs-queues-and-workers</link>
      <pubDate>Wed, 03 Sep 2014 14:20:32 GMT</pubDate>
      <dc:creator><![CDATA[Jeff Levinson (p)]]></dc:creator>
      <guid
        isPermaLink="false">http://qa.msdn.wdslab.com/musings_on_alm_and_software_development_processes/2014/09/03/azure-event-hubs-queues-and-workers/</guid>
      <description><![CDATA[As I’m growing into my role at Microsoft I am discovering that the wealth of new technologies is...]]></description>
      <content:encoded><![CDATA[<p>As I’m growing into my role at Microsoft I am discovering that the wealth of new technologies is almost overwhelming. In many ways, keeping up with the latest material is harder than just sticking with known things and growing slowly. With the fast release cadence at Microsoft, there is literally something new every single day. As part of my role, I get to demonstrate these new features to customers who may be interested in them to solve real world business problems. Sometimes I just get to create fun demos that engage customers and let me learn the new technology – this is one of these demonstrations.</p>  <p>I spoke at VS Live! Redmond a couple of weeks ago and Jason Zander, a Corporate Vice President in the Azure group did just an amazing demo of the new Event Hub feature and I wanted to duplicate it from the ground up. Here’s the basic setup. The demo consists of a web client that sends a message (and the browser being used) to an event hub. The event hub passes it on to a queue (this is mostly because it makes the demo much more fun) and then a client reads out of the queue. The best part is that it happens almost instantaneously.</p>  <p>The main thing to note is that Queues are really designed to be read from sequentially (although you can certainly peek at any message and Event Hubs can have a message processed by many systems at once. The differences between Queues, Topics and Event Hubs can be found here: <a title="http://msdn.microsoft.com/en-us/library/azure/dn789972.aspx" href="http://msdn.microsoft.com/en-us/library/azure/dn789972.aspx">http://msdn.microsoft.com/en-us/library/azure/dn789972.aspx</a>. This example doesn’t show these differences but instead shows the basic techniques of writing and reading to/from hubs and queues. Because Event Hubs are so new, the documentation is extremely limited right now (it’s still in Preview right now in fact).</p>  <p>With all of this said, hopefully this will be helpful and you’ll be able to adapt it for your own purposes… Before beginning I would also like to call out Jeff Wilcox for helping provide a couple of key pieces/ideas for the solution.</p>  <h1>Solution Overview</h1>  <p>The solution consists of an Azure Website which allows users to enter a message. The message is passed to an Event Hub. An Azure Cloud Service Worker processes the Event Hub and passes the message to an Azure Queue. Finally a Wpf application reads the Azure Queue and displays an aggregation of the data to the end user. Conceptually this is similar to a messaging app where 500 people send one person a message at the same time. In more practical terms thing of an Internet of Things (IoT) where thousands of devices send messages every second and that data has to be processed and stored and displayed. So there is a potential real word application for this type of structure.</p>  <h2>Creating the Event Hub</h2>  <p>In the Azure management portal select New &gt; Service Bus &gt; Event Hub as follows:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7652.image_0D85BEE4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7652.image_5F00_0D85BEE4.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8741.image_thumb_16E18418.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8741.image_5F00_thumb_5F00_16E18418.png" width="244" height="94" /></a> </p>  <p>Provide a name (DemoApp in this case):</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7268.image_56AB6A9D.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7268.image_5F00_56AB6A9D.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8357.image_thumb_16755123.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8357.image_5F00_thumb_5F00_16755123.png" width="244" height="162" /></a> </p>  <p>If you don’t already have an existing service bus namespace, it will create one for you (it is automatically appended with “-ns”). This is a mistake that I made originally – my Event Hub and my Queue are in two different namespaces. This is not required – I just made it more complicated for myself.</p>  <p>Next, provide a partition count and days for retention:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5621.SNAGHTML3e38e9e1_042C8A61.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5621.SNAGHTML3e38e9e1_5F00_042C8A61.png"><img title="SNAGHTML3e38e9e1" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="SNAGHTML3e38e9e1" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7367.SNAGHTML3e38e9e1_thumb_38CCE69C.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7367.SNAGHTML3e38e9e1_5F00_thumb_5F00_38CCE69C.png" width="244" height="162" /></a></p>  <p>The partition count is a value between 1 and 32. Click the check mark and the hub will be created. After the hub is created, make sure to click the Connection Information at the bottom of the hub page to grab the string to allow the client applications to send data to and read data from the hub.</p>  <h2>The Web Client – Writing to the Hub</h2>  <p>Before attempting to use an Event Hub you need to add a reference to the right package. To do this, right-click the solution and select Manage NuGet Packages… Search for the Microsoft Azure Service Bus Event Hub – EventProcessorHost. Once you add that you just need to update or add a key with the Event Hub connection data to the web.config file. The page that takes the message is very simple and looks like the following:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8666.image_4AA97A69.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8666.image_5F00_4AA97A69.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8688.image_thumb_1F64E362.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8688.image_5F00_thumb_5F00_1F64E362.png" width="244" height="64" /></a> </p>  <p>This is a standard MVC application which I added an EventHubs page to. The code in the EventHub.cshtml page is as follows:</p>  <pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">@{
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    ViewBag.Title = &quot;<span style="color: #8b0000">Event Hubs</span>&quot;;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">}
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">&lt;p style=&quot;<span style="color: #8b0000">padding-top:20px</span>&quot;&gt;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    Enter a message to send: &lt;input type=&quot;<span style="color: #8b0000">text</span>&quot; id=&quot;<span style="color: #8b0000">message</span>&quot; <span style="color: #0000ff">name</span>=&quot;<span style="color: #8b0000">eventMessage</span>&quot; /&gt;&lt;input type=&quot;<span style="color: #8b0000">button</span>&quot; id=&quot;<span style="color: #8b0000">sendMessageButton</span>&quot; value=&quot;<span style="color: #8b0000">Send Message</span>&quot; /&gt;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">&lt;/p&gt;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">&lt;script type=&quot;<span style="color: #8b0000">text/javascript</span>&quot;&gt;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    $(&quot;<span style="color: #8b0000">#sendMessageButton</span>&quot;).click(<span style="color: #0000ff">function</span>() {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        $.getJSON(getHomeUrl() + &quot;<span style="color: #8b0000">home/SendMessage/?</span>&quot; + $.param({ eventMessage: $(&quot;<span style="color: #8b0000">#message</span>&quot;).val(), browserInfo: $.browser.<span style="color: #0000ff">name</span> }), &quot;<span style="color: #8b0000"></span>&quot;, <span style="color: #0000ff">function</span> () {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">            $(&quot;<span style="color: #8b0000">#message</span>&quot;).val(&quot;<span style="color: #8b0000"></span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">        })
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    })
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">&lt;/script&gt;</pre></pre>

<p>The main work on this page is done by the AJAX call which sends the data to the server. There’s nothing related to the Event Hubs in this page – it’s just standard jQuery.</p>

<p>The Home controller gets this call and does the real work. The main piece is the SendMessage function (be sure to including using Microsoft.ServiceBus.Messaging).</p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"><span style="color: #0000ff">public</span> JsonResult SendMessage(<span style="color: #0000ff">string</span> eventMessage, <span style="color: #0000ff">string</span> browserInfo)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">{
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  <span style="color: #008000">//Put all of the data into a single class</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  EventHubData ehd = <span style="color: #0000ff">new</span> EventHubData() { Message = eventMessage, BrowserInfo = browserInfo };
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  <span style="color: #008000">//serialize it</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  var serializedString = JsonConvert.SerializeObject(ehd);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  <span style="color: #008000">//Create the Event Data object so the data and partition are known</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  EventData data = <span style="color: #0000ff">new</span> EventData(Encoding.Unicode.GetBytes(serializedString))
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">    PartitionKey = &quot;<span style="color: #8b0000">0</span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  };
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  <span style="color: #008000">//Get a reference to the event hub</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  EventHubClient client = EventHubClient.CreateFromConnectionString(ConfigurationManager.AppSettings[&quot;<span style="color: #8b0000">Microsoft.ServiceBus.ConnectionString</span>&quot;], &quot;<span style="color: #8b0000">DemoApp</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  <span style="color: #008000">//Send the data</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  client.SendAsync(data);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"></pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  <span style="color: #008000">//Return to the client</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  <span style="color: #0000ff">return</span> Json(&quot;<span style="color: #8b0000"></span>&quot;, JsonRequestBehavior.AllowGet);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">}</pre></pre>

<p>There is a single class which backs the data and it simply encapsulate the information to send in the message so it can be easily deserialized on the back end. Next the object is serialized and an EventData object is created. The PartitionKey can be whatever you want to call the partition – there are a potential of 32 partitions and you can set this value when you create your event hub – they are referenced by ordinal number so I just lacked incredible creativity by naming it “0”. The next line gets the reference to the event hub in azure and then finally the message is send asynchronously.</p>

<p>That’s all there is to it. As you start sending messages you’ll see the following type of view in Azure (note that this doesn’t update instantaneously):</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7624.image_4632F9A2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7624.image_5F00_4632F9A2.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5141.image_thumb_65E1D36A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5141.image_5F00_thumb_5F00_65E1D36A.png" width="244" height="120" /></a> </p>

<p>So, we can now add data to the event hub! Obviously that in itself isn’t particularly useful so without further ado, moving on!</p>

<h2>Creating the Queue</h2>

<p>This is where you can do it better than I did it. Select the DemoApp-ns namespace from the Azure Management Portal and click the Queues tab.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0602.image_3A9D3C63.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0602.image_5F00_3A9D3C63.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3857.image_thumb_4EB658EC.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3857.image_5F00_thumb_5F00_4EB658EC.png" width="244" height="71" /></a> </p>

<p>Click Create a new Queue. Provide a queue name and select an appropriate region.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5516.image_3C6D922A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5516.image_5F00_3C6D922A.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4530.image_thumb_43209BAD.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4530.image_5F00_thumb_5F00_43209BAD.png" width="244" height="153" /></a> </p>

<p>Click the next arrow and set any additional settings needed then click the check mark.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/8737.image_17DC04A6.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/8737.image_5F00_17DC04A6.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2474.image_thumb_1E8F0E29.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2474.image_5F00_thumb_5F00_1E8F0E29.png" width="244" height="177" /></a> </p>

<p>These settings are discussed more in this great tutorial on Queues: <a title="http://social.technet.microsoft.com/wiki/contents/articles/2173.azure-and-sql-database-tutorials-tutorial-4-using-windows-azure-worker-role-and-windows-azure-queue-service.aspx" href="http://social.technet.microsoft.com/wiki/contents/articles/2173.azure-and-sql-database-tutorials-tutorial-4-using-windows-azure-worker-role-and-windows-azure-queue-service.aspx">http://social.technet.microsoft.com/wiki/contents/articles/2173.azure-and-sql-database-tutorials-tutorial-4-using-windows-azure-worker-role-and-windows-azure-queue-service.aspx</a>.</p>

<p>Remember to grab your connection string!</p>

<p>Now here’s the tricky thing – having a queue isn’t enough. A queue has to store its data somewhere. That somewhere is in a storage service. And not only in a storage service – but in a container in a storage service. Creating this is trivial but if you aren’t aware of it (like I wasn’t because I tend to “do” before I “read” – isn’t that how it is with everyone in the tech industry?) it’s hard to figure it. To create a storage account, go to the storage management page and select New. Create the storage service then click the Containers tab.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/2772.image_734A7721.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/2772.image_5F00_734A7721.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4861.image_thumb_6101B05F.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4861.image_5F00_thumb_5F00_6101B05F.png" width="244" height="48" /></a> </p>

<p>Select new at the bottom and provide a name and click the check mark – you’re done! For this you’re going to need a bit more information to connect to it. On the dashboard page for the storage account you’ll see the following:</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3312.image_20CB96E5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3312.image_5F00_20CB96E5.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5140.image_thumb_0E169D2E.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5140.image_5F00_thumb_5F00_0E169D2E.png" width="244" height="124" /></a> </p>

<p>Grab not only the URL for Queues but also click the Manage Access Keys at the bottom and grab the storage account name and the primary access key as you’ll need these to write to the queue.</p>

<h2>Cloud Service Worker – Reading from the Hub</h2>

<p>At this point we have data in the hub, now we need to process it. For this we’ll create a cloud service which constantly monitors the hub and processes any data that is received.</p>

<p>This took me a while to figure out as it isn’t obvious – you really do need to do it the way it is described in this post – I spent hours trying to work around what I thought was an overly involved process. It turns out that the separation of concerns really is the smartest way to manage this.</p>

<p>The key to reading from an Event Hub is the IEventProcessor interface. After you create a new Cloud Service worker role, add a reference to the event hub (as in the above sample – and also add a reference to the Azure Service Bus because you’ll need that to access the queue). Then add the following class:</p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  1: <span style="color: #0000ff">using</span> Microsoft.ServiceBus.Messaging;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  2: <span style="color: #0000ff">using</span> Microsoft.WindowsAzure.Storage;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  3: <span style="color: #0000ff">using</span> Microsoft.WindowsAzure.Storage.Queue;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  4: <span style="color: #0000ff">using</span> System;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  5: <span style="color: #0000ff">using</span> System.Collections.Generic;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  6: <span style="color: #0000ff">using</span> System.Diagnostics;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  7: <span style="color: #0000ff">using</span> System.Linq;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  8: <span style="color: #0000ff">using</span> System.Text;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  9: <span style="color: #0000ff">using</span> System.Threading.Tasks;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 10: <span style="color: #0000ff">using</span> Newtonsoft.Json.Linq;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 11: <span style="color: #0000ff">using</span> Microsoft.ServiceBus;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 12: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 13: <span style="color: #0000ff">namespace</span> WorkerRole1
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 14: {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 15:     <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> EventProcessor : IEventProcessor
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 16:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 17:         PartitionContext partitionContext;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 18:         Stopwatch checkpointStopWatch;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 19: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 20:         QueueClient queue;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 21: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 22:         <span style="color: #0000ff">public</span> EventProcessor()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 23:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 24:             queue = QueueClient.CreateFromConnectionString(&quot;[your connection string here]&quot;,&quot;<span style="color: #8b0000">[your queue name here]</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 25:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 26: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 27:         <span style="color: #0000ff">public</span> async Task CloseAsync(PartitionContext context, CloseReason reason)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 28:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 29:             Console.WriteLine(<span style="color: #0000ff">string</span>.Format(&quot;<span style="color: #8b0000">Processor Shuting Down.  Partition '{0}', Reason: '{1}'.</span>&quot;, <span style="color: #0000ff">this</span>.partitionContext.Lease.PartitionId, reason.ToString()));
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 30:             <span style="color: #0000ff">if</span> (reason == CloseReason.Shutdown)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 31:             {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 32:                 await context.CheckpointAsync();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 33:             }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 34:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 35: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 36:         <span style="color: #0000ff">public</span> Task OpenAsync(PartitionContext context)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 37:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 38:             Console.WriteLine(<span style="color: #0000ff">string</span>.Format(&quot;<span style="color: #8b0000">SimpleEventProcessor initialize.  Partition: '{0}', Offset: '{1}'</span>&quot;, context.Lease.PartitionId, context.Lease.Offset));
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 39:             <span style="color: #0000ff">this</span>.partitionContext = context;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 40:             <span style="color: #0000ff">this</span>.checkpointStopWatch = <span style="color: #0000ff">new</span> Stopwatch();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 41:             <span style="color: #0000ff">this</span>.checkpointStopWatch.Start();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 42:             <span style="color: #0000ff">return</span> Task.FromResult&lt;<span style="color: #0000ff">object</span>&gt;(<span style="color: #0000ff">null</span>);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 43:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 44: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 45:         <span style="color: #0000ff">public</span> async Task ProcessEventsAsync(PartitionContext context, IEnumerable&lt;EventData&gt; messages)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 46:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 47:             <span style="color: #0000ff">try</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 48:             {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 49:                 <span style="color: #0000ff">foreach</span> (EventData eventData <span style="color: #0000ff">in</span> messages)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 50:                 {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 51:                     Console.WriteLine(&quot;<span style="color: #8b0000">Processing event hub data...</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 52: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 53:                     <span style="color: #0000ff">string</span> key = eventData.PartitionKey;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 54: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 55:                     <span style="color: #0000ff">string</span> data = System.Text.Encoding.Unicode.GetString(eventData.GetBytes());
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 56:                     <span style="color: #0000ff">try</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 57:                     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 58:                         var json = JObject.Parse(data);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 59:                         <span style="color: #0000ff">string</span> text = json[&quot;<span style="color: #8b0000">Message</span>&quot;].ToString();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 60:                         <span style="color: #0000ff">string</span> agent = json[&quot;<span style="color: #8b0000">BrowserInfo</span>&quot;].ToString();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 61: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 62:                         <span style="color: #0000ff">if</span> (queue != <span style="color: #0000ff">null</span>)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 63:                         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 64:                             
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 65:                             await queue.SendAsync(<span style="color: #0000ff">new</span> BrokeredMessage((agent + &quot;<span style="color: #8b0000">##</span>&quot; + text)));
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 66: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 67:                             Trace.TraceInformation(&quot;<span style="color: #8b0000">Added to queue: </span>&quot; + agent);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 68:                         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 69:                     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 70:                     <span style="color: #0000ff">catch</span>(Exception exx)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 71:                     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 72:                         Console.WriteLine(exx.Message);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 73:                     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 74: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 75:                     Console.WriteLine(<span style="color: #0000ff">string</span>.Format(&quot;<span style="color: #8b0000">Message received.  Partition: '{0}', Device: '{1}'</span>&quot;,
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 76:                         <span style="color: #0000ff">this</span>.partitionContext.Lease.PartitionId, key));
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 77:                 }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 78: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 79:                 <span style="color: #008000">//Call checkpoint every 5 minutes, so that worker can resume processing from the 1 minutes back if it restarts.</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 80:                 <span style="color: #008000">// Doing every ONE MINUTE now.</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 81:                 <span style="color: #0000ff">if</span> (<span style="color: #0000ff">this</span>.checkpointStopWatch.Elapsed &gt; TimeSpan.FromMinutes(1))
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 82:                 {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 83:                     await context.CheckpointAsync();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 84:                     <span style="color: #0000ff">lock</span> (<span style="color: #0000ff">this</span>)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 85:                     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 86:                         <span style="color: #0000ff">this</span>.checkpointStopWatch.Reset();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 87:                     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 88:                 }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 89:             }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 90:             <span style="color: #0000ff">catch</span> (Exception exp)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 91:             {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 92:                 Console.WriteLine(&quot;<span style="color: #8b0000">Error in processing: </span>&quot; + exp.Message);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 93:             }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 94:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 95:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 96: }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 97: </pre></pre>

<p>Much of this is boilerplate code so I’ll cover the parts that require the most explanation as it relates to event hubs and queues.</p>

<p>All Console statements are for debugging purposes only – I left them in because you may need them. Being that this is an Azure worker role, these can be made visible in many different ways including using AppInsights.</p>

<p>Line 24 creates the connection to the queue where messages will be passed from the Event Hub. Obviously it’s better to read this from the web.config file. No, I don’t know why I did it this way – it was late :)</p>

<p>Line 45-77, the ProcessEventsAsync method does the bulk of the work and it monitors the event hub (the next code block shows where the connection to this comes from). The EventData contains the message from the client. The first task is to get the data out of the message (Line 55) and the next task is to deserialize it – in this case converting it from JSON to variables we can use (Lines 58-60). Finally it is written to the Queue using a BrokeredMessage object (Line 62-68). </p>

<p>This is all that’s required to read data out of the event hub and place it into the queue. The worker role class manages the lifetime of this object and passes in the necessary configuration information. This class is shown in its entirety here – but most of it is boilerplate – I only changed the OnStart method.</p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  1: <span style="color: #0000ff">using</span> System;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  2: <span style="color: #0000ff">using</span> System.Collections.Generic;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  3: <span style="color: #0000ff">using</span> System.Diagnostics;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  4: <span style="color: #0000ff">using</span> System.Linq;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  5: <span style="color: #0000ff">using</span> System.Net;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  6: <span style="color: #0000ff">using</span> System.Threading;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  7: <span style="color: #0000ff">using</span> System.Threading.Tasks;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  8: <span style="color: #0000ff">using</span> Microsoft.WindowsAzure;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  9: <span style="color: #0000ff">using</span> Microsoft.WindowsAzure.Diagnostics;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 10: <span style="color: #0000ff">using</span> Microsoft.WindowsAzure.ServiceRuntime;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 11: <span style="color: #0000ff">using</span> Microsoft.WindowsAzure.Storage;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 12: <span style="color: #0000ff">using</span> Microsoft.ServiceBus.Messaging;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 13: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 14: <span style="color: #0000ff">namespace</span> WorkerRole1
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 15: {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 16:     <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> WorkerRole : RoleEntryPoint
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 17:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 18:         <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> CancellationTokenSource cancellationTokenSource = <span style="color: #0000ff">new</span> CancellationTokenSource();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 19:         <span style="color: #0000ff">private</span> <span style="color: #0000ff">readonly</span> ManualResetEvent runCompleteEvent = <span style="color: #0000ff">new</span> ManualResetEvent(<span style="color: #0000ff">false</span>);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 20: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 21:         <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> Run()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 22:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 23:             Trace.TraceInformation(&quot;<span style="color: #8b0000">WorkerRole1 is running</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 24: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 25:             <span style="color: #0000ff">try</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 26:             {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 27:                 <span style="color: #0000ff">this</span>.RunAsync(<span style="color: #0000ff">this</span>.cancellationTokenSource.Token).Wait();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 28:             }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 29:             <span style="color: #0000ff">finally</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 30:             {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 31:                 <span style="color: #0000ff">this</span>.runCompleteEvent.Set();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 32:             }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 33:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 34: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 35:         <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">bool</span> OnStart()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 36:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 37:             <span style="color: #008000">// Set the maximum number of concurrent connections</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 38:             ServicePointManager.DefaultConnectionLimit = 12;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 39: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 40:             <span style="color: #008000">// For information on handling configuration changes</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 41:             <span style="color: #008000">// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 42: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 43:             <span style="color: #0000ff">bool</span> result = <span style="color: #0000ff">base</span>.OnStart();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 44: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 45:             Trace.TraceInformation(&quot;<span style="color: #8b0000">WorkerRole1 has been started</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 46: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 47:             <span style="color: #0000ff">string</span> storage = &quot;<span style="color: #8b0000">DefaultEndpointsProtocol=https;AccountName=[your account name here];AccountKey=[your key here</span>&quot;;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 48:             <span style="color: #0000ff">string</span> serviceBus = &quot;<span style="color: #8b0000">Endpoint=sb://[your namespace here].servicebus.windows.net/;SharedAccessKeyName=[your key name here];SharedAccessKey=[your key here]</span>&quot;;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 49:             <span style="color: #0000ff">string</span> eventHubName = &quot;<span style="color: #8b0000">demoapp</span>&quot;;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 50: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 51:             EventHubClient client = EventHubClient.CreateFromConnectionString(serviceBus, eventHubName);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 52:             Trace.TraceInformation(&quot;<span style="color: #8b0000">Consumer group is: </span>&quot; + client.GetDefaultConsumerGroup().GroupName);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 53: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 54:             _host = <span style="color: #0000ff">new</span> EventProcessorHost(&quot;<span style="color: #8b0000">singleworker</span>&quot;, eventHubName, client.GetDefaultConsumerGroup().GroupName, serviceBus, storage);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 55: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 56:             Trace.TraceInformation(&quot;<span style="color: #8b0000">Created event processor host...</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 57: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 58:             <span style="color: #0000ff">return</span> result;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 59:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 60: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 61:         <span style="color: #0000ff">private</span> EventProcessorHost _host;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 62: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 63:         <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> OnStop()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 64:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 65:             Trace.TraceInformation(&quot;<span style="color: #8b0000">WorkerRole1 is stopping</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 66: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 67:             _host.UnregisterEventProcessorAsync().Wait();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 68: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 69:             <span style="color: #0000ff">this</span>.cancellationTokenSource.Cancel();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 70:             <span style="color: #0000ff">this</span>.runCompleteEvent.WaitOne();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 71: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 72:             <span style="color: #0000ff">base</span>.OnStop();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 73: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 74:             Trace.TraceInformation(&quot;<span style="color: #8b0000">WorkerRole1 has stopped</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 75:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 76: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 77:         <span style="color: #0000ff">private</span> async Task RunAsync(CancellationToken cancellationToken)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 78:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 79:             await _host.RegisterEventProcessorAsync&lt;EventProcessor&gt;();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 80: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 81:             <span style="color: #008000">// TODO: Replace the following with your own logic.</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 82:             <span style="color: #0000ff">while</span> (!cancellationToken.IsCancellationRequested)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 83:             {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 84:                 <span style="color: #008000">//Trace.TraceInformation(&quot;Working&quot;);</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 85:                 await Task.Delay(1000);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 86:             }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 87:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 88:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 89: }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 90: </pre></pre>

<p></p>

<p></p>

<p>Lines 47-49 set the account information and identifying names for the storage, service bus and queue which are required by the EventProcessor class. Line 51 creates the EventHub client and line 54 starts the process. Everything else is there to manage the lifetime of the EventProcessor object. This can be published to Azure and it will start reading data from the EventHub immediately upon deployment. The queue dashboard should start to look like the following:</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/5852.image_62D20626.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/5852.image_5F00_62D20626.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3731.image_thumb_17726262.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3731.image_5F00_thumb_5F00_17726262.png" width="244" height="147" /></a> </p>

<h2>WPF Client – Reading from the Queue</h2>

<p>Finally we get to reading data from the queue. It’s important to note that you can do this a million different ways. You can use Node.js or SignalR to do real-time web page applications, pass it to other applications for additional processing (which you can do from the event hubs as well) or virtually anything else you want. You can read it with an Android or iOS app, put it into a tabular model for use with PowerView or hundreds of other applications.</p>

<p>I chose WPF because it showed a mix of different technologies and I’m not as comfortable with Node or SignalR (I’m still learning both of them).</p>

<p>The key to this application is a class called QueueReader – everything is used for the presentation of data. </p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  1: <span style="color: #0000ff">using</span> Microsoft.ServiceBus.Messaging;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  2: <span style="color: #0000ff">using</span> System;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  3: <span style="color: #0000ff">using</span> System.Collections.Generic;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  4: <span style="color: #0000ff">using</span> System.Linq;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  5: <span style="color: #0000ff">using</span> System.Text;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  6: <span style="color: #0000ff">using</span> System.Threading;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  7: <span style="color: #0000ff">using</span> System.Threading.Tasks;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  8: <span style="color: #0000ff">using</span> System.Windows;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  9: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 10: <span style="color: #0000ff">namespace</span> WpfQueueReader
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 11: {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 12:     <span style="color: #0000ff">class</span> QueueReader
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 13:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 14:         QueueClient _queue;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 15:         Thread _thread;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 16:         QueueData _persistentData = <span style="color: #0000ff">new</span> QueueData();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 17: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 18:         <span style="color: #0000ff">public</span> <span style="color: #0000ff">delegate</span> <span style="color: #0000ff">void</span> MessageReceivedEventHandler(<span style="color: #0000ff">object</span> sender, MessageEventArgs e);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 19:         <span style="color: #0000ff">public</span> <span style="color: #0000ff">event</span> MessageReceivedEventHandler MessageReceived;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 20: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 21:         <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> MonitorQueue()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 22:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffff00"> 23:             _queue = QueueClient.CreateFromConnectionString(&quot;<span style="color: #8b0000">[your connection string here]</span>&quot;, &quot;<span style="color: #8b0000">[your queue name here]</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 24: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 25:             BrokeredMessage message = <span style="color: #0000ff">null</span>;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 26:             <span style="color: #0000ff">while</span> (<span style="color: #0000ff">true</span>)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 27:             {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 28:                 <span style="color: #0000ff">try</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 29:                 {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 30:                     <span style="color: #008000">//receive messages from Queue</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 31:                     message = _queue.Receive(TimeSpan.FromSeconds(5));
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 32:                     <span style="color: #0000ff">if</span> (message != <span style="color: #0000ff">null</span>)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 33:                     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 34:                         <span style="color: #0000ff">string</span> m = message.GetBody&lt;<span style="color: #0000ff">string</span>&gt;();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 35:                         <span style="color: #0000ff">string</span>[] values = m.Split(<span style="color: #0000ff">new</span> <span style="color: #0000ff">string</span>[] { &quot;<span style="color: #8b0000">##</span>&quot; }, 2, StringSplitOptions.None);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 36: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 37:                         _persistentData.Message = values[1];
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 38:                         _persistentData.Browsers.Add(values[0]);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 39: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 40:                         Application.Current.Dispatcher.BeginInvoke(<span style="color: #0000ff">new</span> ThreadStart(() =&gt; OnMessageReceived(_persistentData)), <span style="color: #0000ff">null</span>);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 41: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 42:                         <span style="color: #008000">// Further custom message processing could go here...</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 43:                         message.Complete();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 44:                     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 45:                     <span style="color: #0000ff">else</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 46:                     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 47:                         Thread.Sleep(TimeSpan.FromSeconds(5));
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 48:                     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 49:                 }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 50:                 <span style="color: #0000ff">catch</span>(OperationCanceledException)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 51:                 {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 52:                     _queue.Close();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 53:                     
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 54:                 }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 55:             }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 56:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 57: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 58:         <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> EndMonitoring()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 59:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 60:             _queue.Close();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 61:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 62: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 63:         <span style="color: #0000ff">protected</span> <span style="color: #0000ff">void</span> OnMessageReceived(QueueData data)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 64:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 65:             <span style="color: #0000ff">if</span> (MessageReceived != <span style="color: #0000ff">null</span>)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 66:             {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 67:                 MessageReceived(<span style="color: #0000ff">this</span>, <span style="color: #0000ff">new</span> MessageEventArgs(data));
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 68:             }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 69:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 70: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 71:         <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> StartTask()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 72:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 73:             ThreadStart threadStart = <span style="color: #0000ff">new</span> ThreadStart(MonitorQueue);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 74:             _thread = <span style="color: #0000ff">new</span> Thread(threadStart);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 75:             _thread.Start();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 76:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 77: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 78:         <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> EndTask()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 79:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 80:             _thread.Abort();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 81:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 82:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 83: }</pre></pre>

<p>Most of the functionality in this class deals with the fact that it’s running on a background thread. The main portion of this class is the MonitorQueue method. Remember to replace the connection string with your own connection information.</p>

<p>The MonitorQueue method does the following:</p>

<ol>
  <li>Creates a connection to the queue</li>

  <li>Starts an endless loop to check the queue (note that this is a cheap way of doing it and I didn’t want to go crazy just for demo purposes – an excellent article on a better way to do this can be found here: <a title="http://www.developerfusion.com/article/120619/advanced-scenarios-with-windows-azure-queues/" href="http://www.developerfusion.com/article/120619/advanced-scenarios-with-windows-azure-queues/">http://www.developerfusion.com/article/120619/advanced-scenarios-with-windows-azure-queues/</a>)</li>

  <li>Check the queue</li>

  <li>If there is a message, </li>

  <ol>
    <li>Get the data from the message</li>

    <li>Add it to a class </li>

    <li>Raise an event to the UI thread with the data</li>

    <li>Check the queue again</li>
  </ol>

  <li>If there isn’t a message,</li>

  <ol>
    <li>Go back to sleep for five seconds before checking the queue again</li>
  </ol>
</ol>

<p>In the UI, the entire class for the single window looks like the following:</p>

<pre style="overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; width: 650px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  1: <span style="color: #0000ff">using</span> System;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  2: <span style="color: #0000ff">using</span> System.Collections.Generic;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  3: <span style="color: #0000ff">using</span> System.Linq;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  4: <span style="color: #0000ff">using</span> System.Text;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  5: <span style="color: #0000ff">using</span> System.Threading.Tasks;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  6: <span style="color: #0000ff">using</span> System.Windows;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  7: <span style="color: #0000ff">using</span> System.Windows.Controls;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  8: <span style="color: #0000ff">using</span> System.Windows.Data;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  9: <span style="color: #0000ff">using</span> System.Windows.Documents;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 10: <span style="color: #0000ff">using</span> System.Windows.Input;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 11: <span style="color: #0000ff">using</span> System.Windows.Media;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 12: <span style="color: #0000ff">using</span> System.Windows.Media.Imaging;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 13: <span style="color: #0000ff">using</span> System.Windows.Navigation;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 14: <span style="color: #0000ff">using</span> System.Windows.Shapes;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 15: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 16: <span style="color: #0000ff">namespace</span> WpfQueueReader
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 17: {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 18:     <span style="color: #808080">/// &lt;summary&gt;</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 19:     <span style="color: #808080">/// Interaction logic for MainWindow.xaml</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 20:     <span style="color: #808080">/// &lt;/summary&gt;</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 21:     <span style="color: #0000ff">public</span> partial <span style="color: #0000ff">class</span> MainWindow : Window
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 22:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 23:         QueueReader _reader = <span style="color: #0000ff">new</span> QueueReader();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 24: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 25:         <span style="color: #0000ff">public</span> MainWindow()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 26:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 27:             InitializeComponent();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 28:             _reader.MessageReceived += _reader_MessageReceived;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 29:             _reader.StartTask();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 30:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 31: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 32:         <span style="color: #0000ff">void</span> _reader_MessageReceived(<span style="color: #0000ff">object</span> sender, MessageEventArgs e)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 33:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 34:             TextBlock block1 = <span style="color: #0000ff">new</span> TextBlock();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 35:             
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 36:             block1.Text = e.Data.Message;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 37: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 38:             spMessages.Children.Add(block1);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 39:             spBrowsers.DataContext = <span style="color: #0000ff">null</span>;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 40:             spBrowsers.DataContext = e.Data.Browsers;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 41:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 42: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 43:         <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> btnExit_Click(<span style="color: #0000ff">object</span> sender, RoutedEventArgs e)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 44:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 45:             _reader.EndMonitoring();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 46:             _reader.EndTask();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 47:             <span style="color: #0000ff">this</span>.Close();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 48:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 49: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 50:         <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> Window_Closed(<span style="color: #0000ff">object</span> sender, EventArgs e)
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 51:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 52:             _reader.EndMonitoring();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 53:             _reader.EndTask();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 54:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 55:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 56: }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 57: </pre></pre>

<p>The constructor here (Lines 25-30) start the background process executing and wires up the event to the UI. The _reader_MessageRecieved method gets the data and simply appends values and re-binds the a collection of browsers to display. The end result of all of this looks like the following:</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/3324.image_0933E972.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/3324.image_5F00_0933E972.png"><img title="image" style="border-top: 0px; border-right: 0px; border-bottom: 0px; border-left: 0px; display: inline" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/7127.image_thumb_0BDCA523.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/7127.image_5F00_thumb_5F00_0BDCA523.png" width="244" height="135" /></a> </p>

<p>In a real time fashion, data is transmitted from the browser, to Azure and back to the WpfQueueReader.</p>

<p>Now, set your imaginations to work because this has real world applications! And it’s never been this easy to build a scalable, distributed application.</p>]]></content:encoded>
    </item>
    <item>
      <title>Unit Testing MDX</title>
      <link>https://docs.microsoft.com/archive/blogs/musings_on_alm_and_software_development_processes/unit-testing-mdx</link>
      <pubDate>Sun, 31 Aug 2014 08:04:01 GMT</pubDate>
      <dc:creator><![CDATA[Jeff Levinson (p)]]></dc:creator>
      <guid
        isPermaLink="false">http://qa.msdn.wdslab.com/musings_on_alm_and_software_development_processes/2014/08/31/unit-testing-mdx/</guid>
      <description><![CDATA[I was recently asked if it was possible to do some smoke testing on new deployments of SQL Server...]]></description>
      <content:encoded><![CDATA[<p>I was recently asked if it was possible to do some smoke testing on new deployments of SQL Server Analysis Services cubes. My initial answer was “yes, of course” – then someone asked me to actually do it. It turns out to be as easy as I thought it was but I wasn’t able to find any particular blog posts regarding how to do it so here goes. In order to perform unit tests against a cube, do the following:</p>  <ol>   <li>Create a new C# (or VB) Unit Test Project </li>    <li>From the SQL Server 2014 (or SQL Server 2012 – but for SQL Server 2012 this is all built into Visual Studio) feature pack download page (<a href="http://www.microsoft.com/en-us/download/details.aspx?id=42295">http://www.microsoft.com/en-us/download/details.aspx?id=42295</a>) select Download and select the 32 or 64 bit version of ADOMD.NET </li>    <li>Add a reference to the Microsoft.AnalysisServices.AdomdClient.dll (located in C:\Program Files\Microsoft.NET\ADOMD.NET\120) </li>    <li>Add a reference to System.Data </li>    <li>Import the namespace Microsoft.AnalysisServices.Adomd </li> </ol>  <p>You’re ready to go. The following is a simple unit test again the TFS Analysis cube:</p>  <pre style="overflow: auto; border-top: #cecece 1px solid; height: 746px; border-right: #cecece 1px solid; width: 621px; border-bottom: #cecece 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; min-height: 40px; border-left: #cecece 1px solid; padding-right: 5px; background-color: #fbfbfb"><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  1: <span style="color: #0000ff">using</span> System;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  2: <span style="color: #0000ff">using</span> Microsoft.VisualStudio.TestTools.UnitTesting;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  3: <span style="color: #0000ff">using</span> Microsoft.AnalysisServices.AdomdClient;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  4: <span style="color: #0000ff">using</span> System.Diagnostics;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  5: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  6: <span style="color: #0000ff">namespace</span> dwUnitTests
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  7: {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff">  8:     [TestClass]
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb">  9:     <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> UnitTest1
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 10:     {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 11:         [TestMethod]
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 12:         <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> TestMethod1()
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 13:         {
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 14:             <span style="color: #008000">//Create the connection to the cube using integrated authentication</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 15:             AdomdConnection connection = <span style="color: #0000ff">new</span> AdomdConnection(&quot;<span style="color: #8b0000">Data Source=Olympia;Initial Catalog=Tfs_Analysis</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 16:             <span style="color: #008000">//Create the command and initialize it</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 17:             AdomdCommand command = <span style="color: #0000ff">new</span> AdomdCommand();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 18:                         
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 19:             <span style="color: #008000">//Provide the MDX to retrieve data from the cube</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 20:             command.CommandText = &quot;<span style="color: #8b0000">SELECT NON EMPTY { [Measures].[Work Item Count] } ON COLUMNS, </span>&quot; 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 21:                 + &quot;<span style="color: #8b0000">NON EMPTY { ([Work Item].[System_WorkItemType].[System_WorkItemType].ALLMEMBERS ) } ON ROWS </span>&quot;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 22:                 + &quot;<span style="color: #8b0000">FROM [Team System]</span>&quot;;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 23: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 24:             <span style="color: #008000">//Set the connection for the command</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 25:             command.Connection = connection;
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 26: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 27:             <span style="color: #008000">//Open a connection to the cube</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 28:             connection.Open();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 29: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 30:             <span style="color: #008000">//Retrieve the data</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 31:             CellSet cs = command.ExecuteCellSet();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 32: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 33:             <span style="color: #008000">//Close the connection</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 34:             connection.Close();
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 35: 
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 36:             <span style="color: #008000">//Validate the data</span>
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 37:             Assert.IsTrue(cs.Axes[1].Positions[0].Members[0].Name == &quot;<span style="color: #8b0000">[Work Item].[System_WorkItemType].&amp;[Bug]</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 38:             Assert.IsTrue((<span style="color: #0000ff">int</span>)cs.Cells[0].Value == 3);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 39:             Assert.IsTrue(cs.Axes[1].Positions[1].Members[0].Name == &quot;<span style="color: #8b0000">[Work Item].[System_WorkItemType].&amp;[Product Backlog Item]</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 40:             Assert.IsTrue((<span style="color: #0000ff">int</span>)cs.Cells[1].Value == 1);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 41:             Assert.IsTrue(cs.Axes[1].Positions[2].Members[0].Name == &quot;<span style="color: #8b0000">[Work Item].[System_WorkItemType].&amp;[Task]</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 42:             Assert.IsTrue((<span style="color: #0000ff">int</span>)cs.Cells[2].Value == 4);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 43:             Assert.IsTrue(cs.Axes[1].Positions[3].Members[0].Name == &quot;<span style="color: #8b0000">[Work Item].[System_WorkItemType].&amp;[Test Case]</span>&quot;);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 44:             Assert.IsTrue((<span style="color: #0000ff">int</span>)cs.Cells[3].Value == 2);
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 45:         }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 46:     }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #fbfbfb"> 47: }
</pre><pre style="font-size: 12px; font-family: consolas,&#39;Courier New&#39;,courier,monospace; width: 100%; margin: 0em; background-color: #ffffff"> 48: </pre></pre>

<p>A couple of things to make life easier. I don’t write MDX that often and I can never remember the syntax when I have to. I had though that the most difficult part of this would be creating the select statement (line 20). It turns out you can do it without any work at all. To generate the MDX statement:</p>

<ul>
  <li>Open SQL Server Management Studio and connect to your cube </li>

  <li>Browse the cube and create the dataset that you want returned as shown in Figure 1 </li>
</ul>
<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4721.image_2A0DBB8E.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4721.image_5F00_2A0DBB8E.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0844.image_thumb_6C142ACF.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0844.image_5F00_thumb_5F00_6C142ACF.png" width="244" height="158" /></a> 

<p><em>Figure 1 – Browse view of an Analysis Services cube</em></p>

<ul>
  <li>Next, click the Design button on the right side of the toolbar to unselect it which results in the view shown in Figure 2 </li>
</ul>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/4657.image_607E6D90.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/4657.image_5F00_607E6D90.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/66/02/metablogapi/0451.image_thumb_20485416.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-66-02-metablogapi/0451.image_5F00_thumb_5F00_20485416.png" width="244" height="118" /></a></p>

<p><em>Figure 2 – MDX View to provide the result set shown in Figure 1</em></p>

<ul>
  <li>At this point, just copy the MDX, remove the formatting options (including and everything following the “Cell Properties”) and you’re done! </li>
</ul>

<p>A word of caution on the Assert statements. I am using Axes and Positions to get the values here because I am using ExecuteCellSet to retrieve the data. There are other methods of retrieving the data so be careful when constructing the assert statements. It took me a bit of trial and error to be able to drill through the object model in debug mode to figure out what I should be testing.</p>

<p>And that’s it – you can now perform quality checks on the results of a cube to ensure that the cube is processing correctly. This probably does not apply to very many people but for those that it does apply to, using proper software development techniques for cube development is every bit as important as using these techniques elsewhere. Maybe more so because end users rely on data from cubes to drive business decisions – if this data is wrong…</p>]]></content:encoded>
    </item>
  </channel>
</rss>