<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Maarten Balliauw {blog}</title>
    <description>ASP.NET, ASP.NET MVC, Windows Azure, PHP, ...</description>
    <link>http://blog.maartenballiauw.be/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 2.0.0.36</generator>
    <language>en-US</language>
    <blogChannel:blogRoll>http://blog.maartenballiauw.be/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Maarten Balliauw</dc:creator>
    <dc:title>Maarten Balliauw {blog}</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/maartenballiauw" /><feedburner:info uri="maartenballiauw" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>SymbolSource support for NuGet Package Source Discovery</title>
      <description>&lt;p&gt;A couple of weeks, I told you about &lt;a href="http://blog.maartenballiauw.be/post/2013/03/18/NuGet-Package-Source-Discovery.aspx"&gt;NuGet Package Source Discovery&lt;/a&gt;. In short, it allows you to add some meta information to your website and use your website as a discovery document for NuGet feeds. And thanks to a &lt;a href="https://github.com/myget/PackageSourceDiscovery"&gt;contribution to the spec&lt;/a&gt; by Marcin from &lt;a href="http://www.SymbolSource.org"&gt;SymbolSource.org&lt;/a&gt;, Package Source Discovery (PSD) now supports configuring Visual Studio for consuming symbols as well. Nifty!&lt;/p&gt;  &lt;h2&gt;An example&lt;/h2&gt;  &lt;p&gt;Let’s go with an example. If we discover packages from my blog, some feeds will be added to NuGet in Visual Studio.&lt;/p&gt;  &lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:e2cc493b-41b5-48ff-b07f-47eb7e68b5c4" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 42px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;Install&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;Package DiscoverPackageSources
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;Discover&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;PackageSources &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;Url &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://blog.maartenballiauw.be&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Because my blog links to my feeds on &lt;a href="http://www.myget.org"&gt;MyGet&lt;/a&gt;, I can provide my MyGet credentials with it:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:f24098de-a4ec-47c2-982f-f65491a04905" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 43px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;Install&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;Package DiscoverPackageSources
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;Discover&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;PackageSources &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;Url &lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://blog.maartenballiauw.be&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;Username maarten &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;Password s3cr3t&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Note I’ve stripped out some of the secrets in the examples but I’m sure you get the idea.&lt;/p&gt;

&lt;p&gt;What’s interesting is that because I provided credentials, MyGet also returned the SymbolSource URL for my feeds and it registered them automatically in Visual Studio.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_278.png"&gt;&lt;img title="Symbol server" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="Symbol server" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_239.png" width="484" height="284" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that’s what I call being lazy in a professional manner!&lt;/p&gt;

&lt;h2&gt;On a side note… NuGet Feed Discovery&lt;/h2&gt;

&lt;p&gt;While not completely related to SymbolSource support, it’s worth mentioning that Package Source Discovery also got support for that other NuGet discovery protocol by the guys at &lt;a href="http://www.inedo.com"&gt;Inedo&lt;/a&gt;, &lt;a href="http://nugetext.org/nuget-feed-discovery"&gt;NuGet Feed Discovery (NFD)&lt;/a&gt;. NFD differs from PSD in that both specs have a different intent.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;NFD is a convention-based API endpoint for listing feeds on a server &lt;/li&gt;

  &lt;li&gt;PSD is a means of discovering feeds from any URL given&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fun thing is: if you add an NFD url to your web site’s metadata, it will also be added into Visual Studio by using NuGet Package Source Discovery. For reference, here’s an example where I add my local NuGet feeds to my blog for discovery:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:36d4df11-776d-4710-b9b9-809b271fde1b" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 61px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #0000FF;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;link &lt;/span&gt;&lt;span style="color: #FF0000;"&gt;rel&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;=&amp;quot;nuget&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; 
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;      type&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;=&amp;quot;application/atom+xml&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; 
&lt;/span&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;      title&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;=&amp;quot;Local feeds&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; 
&lt;/span&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; &lt;span style="color: #FF0000;"&gt;      href&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;=&amp;quot;http://localhost:8888/nugetext/discover-feeds&amp;quot;&lt;/span&gt;&lt;span style="color: #FF0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kLM-OnSZesI:UtGQXi-BH5g:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kLM-OnSZesI:UtGQXi-BH5g:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?i=kLM-OnSZesI:UtGQXi-BH5g:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kLM-OnSZesI:UtGQXi-BH5g:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kLM-OnSZesI:UtGQXi-BH5g:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kLM-OnSZesI:UtGQXi-BH5g:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kLM-OnSZesI:UtGQXi-BH5g:Jwdi1b3fU3Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=Jwdi1b3fU3Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/maartenballiauw/~4/kLM-OnSZesI" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/maartenballiauw/~3/kLM-OnSZesI/post.aspx</link>
      <comments>http://blog.maartenballiauw.be/post/2013/04/11/SymbolSource-support-for-NuGet-Package-Source-Discovery.aspx#comment</comments>
      <guid isPermaLink="false">http://blog.maartenballiauw.be/post.aspx?id=36dc9615-8c13-4112-b523-ad6e085bc975</guid>
      <pubDate>Thu, 11 Apr 2013 11:46:02 +0200</pubDate>
      <category>ASP.NET</category>
      <category>C#</category>
      <category>General</category>
      <category>ICT</category>
      <category>NuGet</category>
      <dc:publisher>maartenba</dc:publisher>
      <pingback:server>http://blog.maartenballiauw.be/pingback.axd</pingback:server>
      <pingback:target>http://blog.maartenballiauw.be/post.aspx?id=36dc9615-8c13-4112-b523-ad6e085bc975</pingback:target>
      <slash:comments>9</slash:comments>
      <trackback:ping>http://blog.maartenballiauw.be/trackback.axd?id=36dc9615-8c13-4112-b523-ad6e085bc975</trackback:ping>
      <wfw:comment>http://blog.maartenballiauw.be/post/2013/04/11/SymbolSource-support-for-NuGet-Package-Source-Discovery.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.maartenballiauw.be/syndication.axd?post=36dc9615-8c13-4112-b523-ad6e085bc975</wfw:commentRss>
    <feedburner:origLink>http://blog.maartenballiauw.be/post.aspx?id=36dc9615-8c13-4112-b523-ad6e085bc975</feedburner:origLink></item>
    <item>
      <title>Running unit tests when deploying ASP.NET to Windows Azure Web Sites</title>
      <description>&lt;p&gt;&lt;img title="Deployment failed" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: right; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="Deployment failed" align="right" src="http://blog.maartenballiauw.be/image.axd?picture=image_273.png" width="240" height="85" /&gt;One of the well-loved features of Windows Azure Web Sites is the fact that you can simply push our ASP.NET application’s source code to the platform using Git (or TFS or DropBox) and that sources are compiled and deployed on your Windows Azure Web Site. If you’ve checked the management portal earlier, you may have noticed that a number of deployment steps are executed: the deployment process searches for the project file to compile, compiles it, copies the build artifacts to the web root and has your website running. But did you know you can customize this process?&lt;/p&gt;  &lt;h2&gt;Customizing the build process&lt;/h2&gt;  &lt;p&gt;To get an understanding of how to customize the build process, I want to explain you how this works. In the root of your repository, you can add a &lt;em&gt;.deployment&lt;/em&gt; file, containing a simple directive: which command should be run upon deployment.&lt;/p&gt;  &lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:6609690e-8533-46d5-a3dc-9f8a0bbca720" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 46px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #800000; font-weight: bold;"&gt;[&lt;/span&gt;&lt;span style="color: #800000;"&gt;config&lt;/span&gt;&lt;span style="color: #800000; font-weight: bold;"&gt;]&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;command &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; build.bat&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;This command can be a batch file, a PHP file, a bash file and so on. As long as we can tell Windows Azure Web Sites what to execute. Let’s go with a batch file.&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:5d417a74-2cad-4d5b-9926-acc820b72467" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 42px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #0000FF;"&gt;@echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;off&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; This is a custom deployment script&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; yay!&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;When pushing this to Windows Azure Web Sites, here’s what you’ll see:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_274.png"&gt;&lt;img title="Windows Azure Web Sites custom build" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="Windows Azure Web Sites custom build" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_235.png" width="484" height="203" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this batch file, we can use some environment variables to further customize the script:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;DEPLOYMENT_SOURCE - The initial &amp;quot;working directory&amp;quot; &lt;/li&gt;

  &lt;li&gt;DEPLOYMENT_TARGET - The wwwroot path (deployment destination) &lt;/li&gt;

  &lt;li&gt;DEPLOYMENT_TEMP - Path to a temporary directory (removed after the deployment) &lt;/li&gt;

  &lt;li&gt;MSBUILD_PATH - Path to msbuild &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After compiling, you can simply xcopy our application to the %DEPLOYMENT_TARGET% variable and have your website live.&lt;/p&gt;

&lt;h2&gt;Generating deployment scripts&lt;/h2&gt;

&lt;p&gt;Creating deployment scripts can be a tedious job, good thing that the &lt;a href="http://www.windowsazure.com/en-us/manage/linux/other-resources/command-line-tools/"&gt;azure-cli&lt;/a&gt; tools are there! Once those are installed, simply invoke the following command and have both the &lt;em&gt;.deployment&lt;/em&gt; file as well as a batch or bash file generated:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:a0a6996a-38a9-402e-b40d-277fdea03364" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 21px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;azure site deploymentscript --aspWAP &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;path\to\project.csproj&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;For reference, here’s what is generated:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:4c59b882-cb32-476c-ae50-02867f0abbf4" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 367px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000FF;"&gt;@echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;off&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; ----------------------&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; KUDU Deployment Script&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; ----------------------&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; Prerequisites&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; -------------&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; Verify node.js installed&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;where node &lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;nul &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;nul
&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; %&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;ERRORLEVEL&lt;/span&gt;&lt;span style="color: #000000;"&gt;% NEQ &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Missing node&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;js executable&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; please install node&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;js&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; already installed make sure it can be reached from current environment&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;goto&lt;/span&gt;&lt;span style="color: #000000;"&gt; error
&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; Setup&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; -----&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;setlocal&lt;/span&gt;&lt;span style="color: #000000;"&gt; enabledelayedexpansion
&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;SET&lt;/span&gt;&lt;span style="color: #000000;"&gt; ARTIFACTS&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;%~dp0%artifacts
&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NOT&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEFINED DEPLOYMENT_SOURCE &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;SET&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEPLOYMENT_SOURCE&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;%~dp0%&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NOT&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEFINED DEPLOYMENT_TARGET &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;SET&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEPLOYMENT_TARGET&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;%ARTIFACTS%&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;wwwroot
&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NOT&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEFINED NEXT_MANIFEST_PATH &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;SET&lt;/span&gt;&lt;span style="color: #000000;"&gt; NEXT_MANIFEST_PATH&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;%ARTIFACTS%&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;manifest
&lt;/span&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NOT&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEFINED PREVIOUS_MANIFEST_PATH &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;SET&lt;/span&gt;&lt;span style="color: #000000;"&gt; PREVIOUS_MANIFEST_PATH&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;%ARTIFACTS%&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;manifest
&lt;/span&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NOT&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEFINED KUDU_SYNC_COMMAND &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; Install kudu sync&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Installing Kudu Sync
&lt;/span&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;call&lt;/span&gt;&lt;span style="color: #000000;"&gt; npm install kudusync -g --silent
&lt;/span&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; !&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;ERRORLEVEL&lt;/span&gt;&lt;span style="color: #000000;"&gt;! NEQ &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;goto&lt;/span&gt;&lt;span style="color: #000000;"&gt; error
&lt;/span&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; Locally just running &amp;quot;kuduSync&amp;quot; would also work&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;SET&lt;/span&gt;&lt;span style="color: #000000;"&gt; KUDU_SYNC_COMMAND&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;node &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%appdata%\npm\node_modules\kuduSync\bin\kuduSync&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NOT&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEFINED DEPLOYMENT_TEMP &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;SET&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEPLOYMENT_TEMP&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;%temp%&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;___deployTemp%random%
&lt;/span&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;SET&lt;/span&gt;&lt;span style="color: #000000;"&gt; CLEAN_LOCAL_DEPLOYMENT_TEMP&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;true
&lt;/span&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEFINED CLEAN_LOCAL_DEPLOYMENT_TEMP &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;EXIST&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%DEPLOYMENT_TEMP%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;rd&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;s &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;q &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%DEPLOYMENT_TEMP%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;mkdir&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%DEPLOYMENT_TEMP%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NOT&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEFINED MSBUILD_PATH &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;SET&lt;/span&gt;&lt;span style="color: #000000;"&gt; MSBUILD_PATH&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;%WINDIR%&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;Microsoft&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NET&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;Framework&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;v4&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;0.30319&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;msbuild&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;exe
&lt;/span&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt; &lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; Deployment&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt; &lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; ----------&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Handling &lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NET&lt;/span&gt;&lt;span style="color: #000000;"&gt; Web Application deployment&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;68&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;69&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; 1. Build to the temporary path&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;70&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%MSBUILD_PATH% &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%DEPLOYMENT_SOURCE%\path.csproj&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;nologo &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;verbosity&lt;/span&gt;&lt;span style="color: #800000;"&gt;:m&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;t&lt;/span&gt;&lt;span style="color: #800000;"&gt;:pipelinePreDeployCopyAllFilesToOneFolder&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;p&lt;/span&gt;&lt;span style="color: #800000;"&gt;:_PackageTempDir&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%DEPLOYMENT_TEMP%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;span style="color: #000000;"&gt;AutoParameterizationWebConfigConnectionStrings&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;false&lt;/span&gt;&lt;span style="color: #000000;"&gt;;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Configuration&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;Release
&lt;/span&gt;&lt;span style="color: #008080;"&gt;71&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; !&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;ERRORLEVEL&lt;/span&gt;&lt;span style="color: #000000;"&gt;! NEQ &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;goto&lt;/span&gt;&lt;span style="color: #000000;"&gt; error
&lt;/span&gt;&lt;span style="color: #008080;"&gt;72&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;73&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; 2. KuduSync&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;74&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Kudu Sync from &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%DEPLOYMENT_TEMP%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; to &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%DEPLOYMENT_TARGET%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;75&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;call&lt;/span&gt;&lt;span style="color: #000000;"&gt; %KUDU_SYNC_COMMAND% -q -f &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%DEPLOYMENT_TEMP%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; -t &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%DEPLOYMENT_TARGET%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; -n &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%NEXT_MANIFEST_PATH%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; -p &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%PREVIOUS_MANIFEST_PATH%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; -i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;.git;.deployment;deploy.cmd&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;nul
&lt;/span&gt;&lt;span style="color: #008080;"&gt;76&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; !&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;ERRORLEVEL&lt;/span&gt;&lt;span style="color: #000000;"&gt;! NEQ &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;goto&lt;/span&gt;&lt;span style="color: #000000;"&gt; error
&lt;/span&gt;&lt;span style="color: #008080;"&gt;77&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;78&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;79&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;80&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;goto&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;end&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;81&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;82&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;:error&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;83&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; An error has occured during web site deployment&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;84&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;exit&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;b &lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;85&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;86&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;:end&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;87&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Finished successfully&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;88&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;This script does a couple of things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ensure node.js is installed on Windows Azure Web Sites (needed later on for synchronizing files) &lt;/li&gt;

  &lt;li&gt;Setting up a bunch of environment variables &lt;/li&gt;

  &lt;li&gt;Run msbuild on the project file we specified &lt;/li&gt;

  &lt;li&gt;Use kudusync (a node.js based tool, hence node.js) to synchronize modified files to the wwwroot of our site &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try it: after pushing this to Windows Azure Web Sites, you’ll see the custom script being used. Not much added value so far, but that’s what you have to provide.&lt;/p&gt;

&lt;h2&gt;Unit testing before deploying&lt;/h2&gt;

&lt;p&gt;Unit tests would be nice! All you need is a couple of unit tests and a test runner. You can add it to your repository and store it there, or simply download it during the deployment. In my example, I’m using the &lt;a href="http://www.gallio.org"&gt;Gallio test runner&lt;/a&gt; because it runs almost all test frameworks, but feel free to use the test runner for NUnit or xUnit instead.&lt;/p&gt;

&lt;p&gt;Somewhere before the line that invokes msbuild and ideally in the “setup” region of the deployment script, add the following:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:e40cf48b-6425-48cc-a684-b9a9ca1797d5" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 318px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NOT&lt;/span&gt;&lt;span style="color: #000000;"&gt; DEFINED GALLIO_COMMAND &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;NOT&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;EXIST&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%appdata%\Gallio\bin\Gallio.Echo.exe&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;(&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; Downloading unzip&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Downloading unzip
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;    curl -O http:&lt;/span&gt;&lt;span style="color: #000000;"&gt;//&lt;/span&gt;&lt;span style="color: #000000;"&gt;stahlforce&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;com&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;dev&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;unzip&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;exe
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; !&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;ERRORLEVEL&lt;/span&gt;&lt;span style="color: #000000;"&gt;! NEQ &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;goto&lt;/span&gt;&lt;span style="color: #000000;"&gt; error
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; Downloading Gallio&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Downloading Gallio
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;    curl -O http:&lt;/span&gt;&lt;span style="color: #000000;"&gt;//&lt;/span&gt;&lt;span style="color: #000000;"&gt;mb-unit&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;googlecode&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;com&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;files&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;GallioBundle-&lt;/span&gt;&lt;span style="color: #000000;"&gt;3.4&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;14.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;zip
&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; !&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;ERRORLEVEL&lt;/span&gt;&lt;span style="color: #000000;"&gt;! NEQ &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;goto&lt;/span&gt;&lt;span style="color: #000000;"&gt; error
&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; Extracting Gallio&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Extracting Gallio
&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;    unzip -q -n GallioBundle-&lt;/span&gt;&lt;span style="color: #000000;"&gt;3.4&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;14.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;zip -d %appdata%&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;Gallio
&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; !&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;ERRORLEVEL&lt;/span&gt;&lt;span style="color: #000000;"&gt;! NEQ &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;goto&lt;/span&gt;&lt;span style="color: #000000;"&gt; error
&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #008000;"&gt;::&lt;/span&gt;&lt;span style="color: #008000;"&gt; Set Gallio runner path&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;SET&lt;/span&gt;&lt;span style="color: #000000;"&gt; GALLIO_COMMAND&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;%appdata%&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;Gallio&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;bin&lt;/span&gt;&lt;span style="color: #000000;"&gt;\&lt;/span&gt;&lt;span style="color: #000000;"&gt;Gallio&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;Echo&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;exe
&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;See what happens there?&amp;#160; We check if the local system on which your files are stored in WindowsAzure Web Sites already has a copy of the &lt;em&gt;Gallio.Echo.exe&lt;/em&gt;test runner. If not, let’s download a tool which allows us to unzip. Next, the entire Gallio test runner is downloaded and extracted. As a final step, the %GALLIO_COMMAND% variable is populated with the full path to the test runner executable.&lt;/p&gt;

&lt;p&gt;Right before the line that calls “kudusync”, add the following:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:397f74dd-aeff-4752-a2e1-ff93f793cad8" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 49px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Running unit tests
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%GALLIO_COMMAND%&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;%DEPLOYMENT_SOURCE%\SampleApp.Tests\bin\Release\SampleApp.Tests.dll&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;IF&lt;/span&gt;&lt;span style="color: #000000;"&gt; !&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;ERRORLEVEL&lt;/span&gt;&lt;span style="color: #000000;"&gt;! NEQ &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;goto&lt;/span&gt;&lt;span style="color: #000000;"&gt; error&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Yes, the name of your test assembly will be different, you should obviously change that. What happens here? Well, we’re invoking the test runner on our unit tests. If it fails, we abort deployment. Push it to Windows Azure and see for yourself. Here’s what is displayed on success:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_275.png"&gt;&lt;img title="Windows Azure Web Site unit tests" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="Windows Azure Web Site unit tests" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_236.png" width="484" height="248" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All green! And on failure, we get:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_276.png"&gt;&lt;img title="Gallio test runner Windows Azure" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="Gallio test runner Windows Azure" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_237.png" width="484" height="248" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the portal, you can clearly see that deployment was aborted:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_277.png"&gt;&lt;img title="Deployment fail when unit tests fail" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; border-top-width: 0px; margin-right: auto" border="0" alt="Deployment fail when unit tests fail" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_238.png" width="484" height="158" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it. Enjoy!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kuaBKb2IT8A:Rq5LfPchJd0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kuaBKb2IT8A:Rq5LfPchJd0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?i=kuaBKb2IT8A:Rq5LfPchJd0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kuaBKb2IT8A:Rq5LfPchJd0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kuaBKb2IT8A:Rq5LfPchJd0:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kuaBKb2IT8A:Rq5LfPchJd0:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=kuaBKb2IT8A:Rq5LfPchJd0:Jwdi1b3fU3Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=Jwdi1b3fU3Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/maartenballiauw/~4/kuaBKb2IT8A" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/maartenballiauw/~3/kuaBKb2IT8A/post.aspx</link>
      <comments>http://blog.maartenballiauw.be/post/2013/03/26/Running-unit-tests-when-deploying-ASPNET-to-Windows-Azure-Web-Sites.aspx#comment</comments>
      <guid isPermaLink="false">http://blog.maartenballiauw.be/post.aspx?id=6b48c084-3458-4a5c-8ba1-0aa0f8967577</guid>
      <pubDate>Tue, 26 Mar 2013 09:56:26 +0200</pubDate>
      <category>C#</category>
      <category>General</category>
      <category>ICT</category>
      <category>Source control</category>
      <category>Windows Azure</category>
      <category>Webfarm</category>
      <category>Projects</category>
      <category>NUnit</category>
      <dc:publisher>maartenba</dc:publisher>
      <pingback:server>http://blog.maartenballiauw.be/pingback.axd</pingback:server>
      <pingback:target>http://blog.maartenballiauw.be/post.aspx?id=6b48c084-3458-4a5c-8ba1-0aa0f8967577</pingback:target>
      <slash:comments>10</slash:comments>
      <trackback:ping>http://blog.maartenballiauw.be/trackback.axd?id=6b48c084-3458-4a5c-8ba1-0aa0f8967577</trackback:ping>
      <wfw:comment>http://blog.maartenballiauw.be/post/2013/03/26/Running-unit-tests-when-deploying-ASPNET-to-Windows-Azure-Web-Sites.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.maartenballiauw.be/syndication.axd?post=6b48c084-3458-4a5c-8ba1-0aa0f8967577</wfw:commentRss>
    <feedburner:origLink>http://blog.maartenballiauw.be/post.aspx?id=6b48c084-3458-4a5c-8ba1-0aa0f8967577</feedburner:origLink></item>
    <item>
      <title>NuGet Package Source Discovery</title>
      <description>&lt;p&gt;It&amp;rsquo;s already been 2 years since &lt;a href="http://www.nuget.org"&gt;NuGet&lt;/a&gt; was introduced. This.NET package manager features the concept of feeds, or &amp;ldquo;package sources&amp;rdquo;, on which packages containing .NET libraries and tools can be hosted. In fact, support for feeds inspired us to build &lt;a href="http://www.myget.org"&gt;www.myget.org&lt;/a&gt;. While not all people are aware of this, Microsoft started out with two feeds as well: one for &lt;a href="http://www.nuget.org"&gt;www.nuget.org&lt;/a&gt;, the other one for the Orchard CMS.&lt;/p&gt;
&lt;p&gt;More and more feeds are being created daily, both by Microsoft as well as others. Here&amp;rsquo;s a list of feeds Microsoft has that I know of (there are probably more):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a title="https://www.nuget.org/api/v2/" href="https://www.nuget.org/api/v2/"&gt;https://www.nuget.org/api/v2/&lt;/a&gt;, the official NuGet gallery feed&lt;/li&gt;
&lt;li&gt;&lt;a title="https://nuget.org/api/v2/curated-feeds/windows8-packages" href="https://nuget.org/api/v2/curated-feeds/windows8-packages"&gt;https://nuget.org/api/v2/curated-feeds/windows8-packages&lt;/a&gt;, containing Windows 8 packages&lt;/li&gt;
&lt;li&gt;&lt;a title="http://packages.orchardproject.net/FeedService.svc" href="http://packages.orchardproject.net/FeedService.svc"&gt;http://packages.orchardproject.net/FeedService.svc&lt;/a&gt; where Orchard packages live&lt;/li&gt;
&lt;li&gt;&lt;a title="http://extensions.webmatrix.com/api/feeds/" href="http://extensions.webmatrix.com/api/feeds/"&gt;http://extensions.webmatrix.com/api/feeds/&lt;/a&gt; contains packages for WebMatrix&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wouldn&amp;rsquo;t it be nice if we could add them all to our Visual Studio package sources without having to know these URL&amp;rsquo;s? Meet the &lt;em&gt;&lt;a href="http://psd.myget.org/"&gt;NuGet Package Source Discovery&lt;/a&gt; &lt;/em&gt;specification, or in short: PSD, a specification &lt;a href="http://www.xavierdecoster.com"&gt;Xavier&lt;/a&gt;, &lt;a href="http://www.hanselman.com"&gt;Scott&lt;/a&gt;, &lt;a href="http://www.haacked.com"&gt;Phil&lt;/a&gt;,&amp;nbsp;&lt;a href="http://jeffhandley.com/"&gt;Jeff&lt;/a&gt;, &lt;a href="http://codebetter.com/howarddierking/"&gt;Howard&lt;/a&gt;&amp;nbsp;and myself have been working on (thanks guys!)&lt;/p&gt;
&lt;h2&gt;Package Source Discovery&lt;/h2&gt;
&lt;p&gt;Because PowerShell says more than words, try the following. Open Visual Studio and open any solution. Then issue the following in the Package Manager Console:&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:c97cc545-50b8-4610-92c5-1834d9ae9646" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 35px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;Install&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;Package DiscoverPackageSources
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;Discover&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;PackageSources &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;Url &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://blog.maartenballiauw.be&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;While we&amp;rsquo;re at it, perhaps the Glimpse project has something to discover as well.&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:e27ff413-cffe-4c88-bf03-b21a8b07ae2c" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 25px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;Discover&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;PackageSources &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;Url &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://getglimpse.com&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;Close and re-open Visual Studio and check your package sources. Notice anything new? My blog has provided you with 2 feeds. And you&amp;rsquo;ve also been subscribed to Glimpse&amp;rsquo;s nightly builds feed.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s more. If you would have been authenticated when connecting to my blog, it will yield API keys as well. This allows the PSD client to setup everything that is needed for me to work with my personal feeds, both consuming and producing, by just remembering the URL of my blog.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Package Source Discovery boils down to trust. &lt;/strong&gt;Since you apparently trust me, you can discover feeds from my blog. If you trust Microsoft, discover feeds from &lt;a href="http://www.microsoft.com"&gt;www.microsoft.com&lt;/a&gt;. Do you trust Windows Azure? Get their packages by discovering feeds at &lt;a href="http://www.windowsazure.com"&gt;www.windowsazure.com&lt;/a&gt;. Need your company feeds? Discover them at &lt;a href="http://nuget"&gt;http://nuget&lt;/a&gt;. A lot of options and possibilities there!&lt;/p&gt;
&lt;h2&gt;Recycling standards&lt;/h2&gt;
&lt;p&gt;If you are a blogger and are using Windows Live Writer, you&amp;rsquo;ve already used this before. We&amp;rsquo;ve written the &lt;a href="http://psd.myget.org/"&gt;NuGet Package Source Discovery&lt;/a&gt; specification based on what happens with blogs: when a simple &lt;em&gt;&amp;lt;link /&amp;gt;&lt;/em&gt; element is added to your HTML, you are compatible with feed discovery. Here are the two elements that are listed in the source code for my blog:&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:c24e495f-2b41-4736-b915-9795e8b88386" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 71px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;&amp;lt;link rel&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;nuget&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; type&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;application/atom+xml&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; title&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Maarten Balliauw NuGet feed&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; href&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://www.myget.org/F/maartenballiauw&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;&amp;lt;link rel&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;nuget&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; type&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;application/rsd+xml&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; href&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;http://www.myget.org/Discovery/Feed/googleanalyticstracker&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;The first one points directly to a feed. Using the URL and the title attribute, we can add this one to our NuGet package sources with ease. The second one points to an RSD file, known since ages as the &lt;strong&gt;Really Simple Discovery&lt;/strong&gt; format described on &lt;a href="https://github.com/danielberlinger/rsd"&gt;https://github.com/danielberlinger/rsd&lt;/a&gt;. We&amp;rsquo;ve recycled it to allow a lot of things at the client side. Since not all required metadata can be obtained from the RSD format, the &lt;a href="http://dublincore.org/documents/2012/06/14/dcmi-terms/?v=elements"&gt;Dublin Core schema&lt;/a&gt; is present in the PSD response as well.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an an example:&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:7fbebb01-3b87-4a52-8498-b402a4ea4a84" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 425px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #ff00ff;"&gt;xml version="1.0" encoding="utf-8"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;?&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;rsd &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="1.0"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; xmlns:dc&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="http://purl.org/dc/elements/1.1/"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;service&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;engineName&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MyGet&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;engineName&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;engineLink&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;http://www.myget.org&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;engineLink&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;dc:identifier&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;http://www.myget.org/F/googleanalyticstracker&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;dc:identifier&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;dc:creator&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;maartenba&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;dc:creator&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;    
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;dc:owner&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;maartenba&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;dc:owner&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;dc:title&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Staging feed for GoogleAnalyticsTracker&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;dc:title&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;dc:description&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Staging feed for GoogleAnalyticsTracker&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;dc:description&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; 
&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;homePageLink&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;http://www.myget.org/gallery/googleanalyticstracker&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;homePageLink&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;apis&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;      &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;api &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="nuget-v2-packages"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; preferred&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="true"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; apiLink&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="http://www.myget.org/F/googleanalyticstracker/api/v2"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; blogID&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;=""&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;      &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;api &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="nuget-v2-push"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; preferred&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="true"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; apiLink&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="http://www.myget.org/F/googleanalyticstracker/api/v2/package"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; blogID&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;=""&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;settings&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt;          &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;setting &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="apiKey"&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;abcdefghijkl&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;setting&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;settings&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;span style="color: #000000;"&gt;      &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;api&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;span style="color: #000000;"&gt;      &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000;"&gt;api &lt;/span&gt;&lt;span style="color: #ff0000;"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="nuget-v1-packages"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; preferred&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="false"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; apiLink&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;="http://www.myget.org/F/googleanalyticstracker/api/v1"&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; blogID&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;=""&lt;/span&gt;&lt;span style="color: #ff0000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;apis&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;service&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000;"&gt;rsd&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;As you can see, using RSD we can embed a lot more information about a feed in this document. If we wanted to add a link to someone&amp;rsquo;s GitHub and have a client that wants to use this, we can add another &lt;em&gt;&amp;lt;api /&amp;gt;&lt;/em&gt; element in here.&lt;/p&gt;
&lt;h2&gt;Who is using this?&lt;/h2&gt;
&lt;p&gt;I am (&lt;a href="http://blog.maartenballiauw.be"&gt;http://blog.maartenballiauw.be&lt;/a&gt;), Xavier is (&lt;a href="http://www.xavierdecoster.com"&gt;http://www.xavierdecoster.com&lt;/a&gt;), Glimpse is (&lt;a href="http://getglimpse.com"&gt;http://getglimpse.com&lt;/a&gt;), NancyFX is (&lt;a href="http://www.nancyfx.org/"&gt;http://www.nancyfx.org&lt;/a&gt;) and &lt;a href="http://blog.myget.org/post/2013/03/18/Support-for-Package-Source-Discovery-draft.aspx"&gt;MyGet has implemented several endpoints&lt;/a&gt; as well. Why don't &lt;em&gt;you &lt;/em&gt;join the wonderful world of package source discovery?&lt;/p&gt;
&lt;h2&gt;Feedback needed!&lt;/h2&gt;
&lt;p&gt;This is not part of NuGet out of the box yet. We need your feedback, comments, implementations and so on. Head over to our &lt;a href="https://github.com/myget/PackageSourceDiscovery"&gt;GitHub&lt;/a&gt; repository, read through the spec and all examples and provide us with your thoughts. &lt;a href="https://github.com/myget/PackageSourceDiscovery/wiki"&gt;Try the two clients we&amp;rsquo;ve crafted&lt;/a&gt; (more &lt;a href="http://www.xavierdecoster.com/introducing-a-nuget-exe-extension-for-package-source-discovery"&gt;on Xavier's blog&lt;/a&gt;) and make your NuGet repositories discoverable. Feel free to post a link to your blog below.&lt;/p&gt;
&lt;p&gt;Enjoy and let the commenting begin!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=5Q_9oq_VVmM:kJtM6ZPf9eo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=5Q_9oq_VVmM:kJtM6ZPf9eo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?i=5Q_9oq_VVmM:kJtM6ZPf9eo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=5Q_9oq_VVmM:kJtM6ZPf9eo:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=5Q_9oq_VVmM:kJtM6ZPf9eo:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=5Q_9oq_VVmM:kJtM6ZPf9eo:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=5Q_9oq_VVmM:kJtM6ZPf9eo:Jwdi1b3fU3Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=Jwdi1b3fU3Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/maartenballiauw/~4/5Q_9oq_VVmM" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/maartenballiauw/~3/5Q_9oq_VVmM/post.aspx</link>
      <comments>http://blog.maartenballiauw.be/post/2013/03/18/NuGet-Package-Source-Discovery.aspx#comment</comments>
      <guid isPermaLink="false">http://blog.maartenballiauw.be/post.aspx?id=e4540510-0f6e-4835-911f-86771d1558b5</guid>
      <pubDate>Mon, 18 Mar 2013 19:45:00 +0200</pubDate>
      <category>ASP.NET</category>
      <category>C#</category>
      <category>General</category>
      <category>ICT</category>
      <category>NuGet</category>
      <category>Personal</category>
      <category>Projects</category>
      <category>Software</category>
      <dc:publisher>maartenba</dc:publisher>
      <pingback:server>http://blog.maartenballiauw.be/pingback.axd</pingback:server>
      <pingback:target>http://blog.maartenballiauw.be/post.aspx?id=e4540510-0f6e-4835-911f-86771d1558b5</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://blog.maartenballiauw.be/trackback.axd?id=e4540510-0f6e-4835-911f-86771d1558b5</trackback:ping>
      <wfw:comment>http://blog.maartenballiauw.be/post/2013/03/18/NuGet-Package-Source-Discovery.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.maartenballiauw.be/syndication.axd?post=e4540510-0f6e-4835-911f-86771d1558b5</wfw:commentRss>
    <feedburner:origLink>http://blog.maartenballiauw.be/post.aspx?id=e4540510-0f6e-4835-911f-86771d1558b5</feedburner:origLink></item>
    <item>
      <title>Remote profiling Windows Azure Cloud Services with dotTrace</title>
      <description>&lt;p&gt;&lt;em&gt;Here&amp;rsquo;s another cross-post from our &lt;/em&gt;&lt;a href="http://www.jetbrains.com/dotnet"&gt;&lt;em&gt;JetBrains .NET blog&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. It&amp;rsquo;s focused around dotTrace but there are a lot of tips and tricks around Windows Azure Cloud Services in it as well, especially around working with the load balancer.&amp;nbsp;Enjoy the read!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;With &lt;a href="http://www.jetbrains.com/dottrace"&gt;dotTrace Performance&lt;/a&gt;, we can profile applications running on our local computer &lt;a href="http://blogs.jetbrains.com/dotnet/2012/09/dottrace-remote-profiling/"&gt;as well as on remote machines&lt;/a&gt;. The latter can be very useful when some performance problems only occur on the staging server (or even worse: only in production). And what if that remote server is a Windows Azure Cloud Service?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: in this post we&amp;rsquo;ll be exploring how to setup a Windows Azure Cloud Service for remote profiling using dotTrace, the &amp;ldquo;platform-as-a-service&amp;rdquo; side of Windows Azure. If you are working with regular virtual machines (&amp;ldquo;infrastructure-as-a-service&amp;rdquo;), the only thing you have to do is &lt;/em&gt;&lt;a href="http://www.windowsazure.com/en-us/manage/windows/how-to-guides/setup-endpoints/"&gt;&lt;em&gt;open up any port in the loadbalancer&lt;/em&gt;&lt;/a&gt;&lt;em&gt;, redirect it to the machine&amp;rsquo;s port 9000 (dotTrace&amp;rsquo;s default) and follow the &lt;/em&gt;&lt;a href="http://blogs.jetbrains.com/dotnet/2012/09/dottrace-remote-profiling/"&gt;&lt;em&gt;regular remote profiling workflow&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Preparing your Windows Azure Cloud Service for remote profiling&lt;/h3&gt;
&lt;p&gt;Since we don&amp;rsquo;t have system administrators at hand when working with cloud services, we have to do some of their work ourselves. The most important piece of work is making sure the load balancer in Windows Azure lets dotTrace&amp;rsquo;s traffic through to the server instance we want to profile.&lt;/p&gt;
&lt;p&gt;We can do this by adding an &lt;em&gt;InstanceInput&lt;/em&gt; endpoint type in the web- or worker role&amp;rsquo;s configuration:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_262.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="Windows Azure InstanceInput endpoint" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_224.png" border="0" alt="Windows Azure InstanceInput endpoint" width="640" height="208" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;By default, the Windows Azure load balancer uses a &lt;a href="http://en.wikipedia.org/wiki/Load_balancing_(computing)#Round-robin_DNS"&gt;round-robin&lt;/a&gt; approach in routing traffic to role instances. In essence every request gets routed to a random instance. When profiling later on, we want to target a specific machine. And that&amp;rsquo;s what the &lt;em&gt;InstanceInput&lt;/em&gt; endpoint allows us to do: it opens up a range of ports on the load balancer and forwards traffic to a local port. In the example above, we&amp;rsquo;re opening ports 9000-9019 in the load balancer and forward them to port 9000 on the server. If we want to connect to a specific instance, we can use a port number from this range. Port 9000 will connect to port 9000 on server instance 0. Port 9001 will connect to port 9000 on role instance 1 and so on.&lt;/p&gt;
&lt;p&gt;When deploying, make sure to enable remote desktop for the role as well. This will allow us to connect to a specific machine and start dotTrace&amp;rsquo;s remote agent there.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_263.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="Windows Azure Remote Desktop RDP" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_225.png" border="0" alt="Windows Azure Remote Desktop RDP" width="640" height="429" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s it. Whenever we want to start remote profiling on a specific role instance, we can now connect to the machine directly.&lt;/p&gt;
&lt;h3&gt;Starting a remote profiling session with a specific instance&lt;/h3&gt;
&lt;p&gt;And then that moment is there: we need to profile production!&lt;/p&gt;
&lt;p&gt;First of all, we want to open a remote desktop connection to one of our role instances. In the Windows Azure management portal, we can connect to a specific instance by selecting it and clicking the &lt;em&gt;Connect&lt;/em&gt; button. Save the file that&amp;rsquo;s being downloaded somewhere on your system: we need to change it before connecting.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_264.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="Windows Azure connect to specific role instance" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_226.png" border="0" alt="Windows Azure connect to specific role instance" width="640" height="261" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The reason for saving and not immediately opening the &lt;em&gt;.rdp&lt;/em&gt; file is that we have to copy the dotTrace Remote Agent to the machine. In order to do that we want to enable access to our local drives. Right-click the downloaded &lt;em&gt;.rdp&lt;/em&gt; file and select &lt;strong&gt;&lt;em&gt;Edit&lt;/em&gt;&lt;/strong&gt; from the context menu. Under the &lt;em&gt;Local Resources&lt;/em&gt; tab, check the &lt;em&gt;Drives&lt;/em&gt; option to allow access to our local filesystem.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_265.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="Windows Azure access local filesystem" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_227.png" border="0" alt="Windows Azure access local filesystem" width="521" height="582" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Save the changes and connect to the remote machine. We can now copy the dotTrace Remote Agent to the role instance by copying all files from our local dotTrace installation. The Remote Agent can be found in &lt;em&gt;C:\Program Files (x86)\JetBrains\dotTrace\v5.3\Bin\Remote&lt;/em&gt;, but since the machine in Windows Azure has no clue about that path we have to specify &lt;em&gt;\\tsclient\C\Program Files (x86)\JetBrains\dotTrace\v5.3\Bin\Remote&lt;/em&gt; instead.&lt;/p&gt;
&lt;p&gt;From the copied folder, launch the &lt;em&gt;RemoteAgent.exe&lt;/em&gt;. A console window similar to the one below will appear:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_266.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="image" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_228.png" border="0" alt="image" width="640" height="317" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Not there yet: we did open the load balancer in Windows Azure to allow traffic to flow to our machine, but the machine&amp;rsquo;s own firewall will be blocking our incoming connection. To solve this, configure Windows Firewall to allow access on port 9000. A one-liner which can be run in a command prompt would be the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;netsh advfirewall firewall add rule name="Profiler" dir=in action=allow protocol=TCP localport=9000&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Since we&amp;rsquo;ve opened ports 9000 thru 9019 in the Windows Azure load balancer and every role instance gets their own port number from that range, we can now connect to the machine using dotTrace. We&amp;rsquo;ve connected to instance 1, which means we have to connect to port 9001 in dotTrace&amp;rsquo;s &lt;em&gt;Attach to Process&lt;/em&gt; window. The Remote Agent URL will look like&lt;em&gt; &lt;/em&gt;&lt;em&gt;http://&amp;lt;yourservice&amp;gt;.cloudapp.net:PORT/RemoteAgent/AgentService.asmx&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_267.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="Attach to process" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_229.png" border="0" alt="Attach to process" width="646" height="750" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next, we can select the process we want to do performance tracing on. I&amp;rsquo;ve deployed a web application so I&amp;rsquo;ll be connecting to IIS&amp;rsquo;s &lt;em&gt;w3wp.exe&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_268.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="Profile application dotTrace" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_230.png" border="0" alt="Profile application dotTrace" width="640" height="729" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We can now user our application and try reproducing performance issues. Once we feel we have enough data, the &lt;strong&gt;&lt;em&gt;Get Snapshot&lt;/em&gt;&lt;/strong&gt; button will download all required data from the server for local inspection.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_269.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="dotTrace get performance snapshot" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_231.png" border="0" alt="dotTrace get performance snapshot" width="282" height="279" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We can now perform our performance analysis tasks and hunt for performance issues. We can analyze the snapshot data just as if we had recorded the snapshot locally. After determining the root cause and deploying a fix, we can repeat the process to collect another snapshot and verify that you have resolved the performance problem. Note that all steps in this post should be executed again in the next profiling session: Windows Azure&amp;rsquo;s Cloud Service machines are stateless and will probably discard everything we&amp;rsquo;ve done with them so far.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_270.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="Analyze snapshot data" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_232.png" border="0" alt="Analyze snapshot data" width="640" height="267" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Bonus tip: get the instance being profiled out of the load balancer&lt;/h3&gt;
&lt;p&gt;Since we are profiling a production application, we may get in the way of our users by collecting profiling data. Another issue we have is that our own test data and our live user&amp;rsquo;s data will show up in the performance snapshot. And if we&amp;rsquo;re running a lot of instances, not every action we do in the application will be performed by the role instance we&amp;rsquo;ve connected to because of Windows Azure&amp;rsquo;s round-robin load balancing.&lt;/p&gt;
&lt;p&gt;Ideally we want to temporarily remove the role instance we&amp;rsquo;re profiling from the load balancer to overcome these issues.The good news is: we can do this! The only thing we have to do is add a small piece of code in our &lt;em&gt;WebRole.cs&lt;/em&gt; or &lt;em&gt;WorkerRole.cs&lt;/em&gt; class.&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:15be485d-ab32-4a46-aec8-fa9d89550f22" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 271px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; WebRole &lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;/span&gt;&lt;span style="color: #000000;"&gt; RoleEntryPoint
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;{
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; override bool OnStart()
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; For information on handling configuration changes
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #008000;"&gt;        // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;        RoleEnvironment&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;StatusCheck &lt;/span&gt;&lt;span style="color: #000000;"&gt;+=&lt;/span&gt;&lt;span style="color: #000000;"&gt; (sender&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; args) &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #008080;"&gt;File&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Exists(&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;C:\\Config\\profiling.txt&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;))
&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    args&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;SetBusy();
&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;            };
&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; base&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;OnStart();
&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;Essentially what we&amp;rsquo;re doing here is capturing the load balancer&amp;rsquo;s probes to see if our node is still healthy. We can choose to respond to the load balancer that our current instance is busy and should not receive any new requests. In the example code above we&amp;rsquo;re checking if the file &lt;em&gt;C:\Config\profiling.txt&lt;/em&gt; exists. If it does, we respond the load balancer with a busy status.&lt;/p&gt;
&lt;p&gt;When we start profiling, we can now create the &lt;em&gt;C:\Config\profiling.txt&lt;/em&gt; file to take the instance we&amp;rsquo;re profiling out of the server pool. After about a minute, the management portal will report the instance is &amp;ldquo;Busy&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_271.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="Role instance marked Busy" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_233.png" border="0" alt="Role instance marked Busy" width="288" height="132" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The best thing is we can still attach to the instance-specific endpoint and attach dotTrace to this instance. Just keep in mind that using the application should now happen in the remote desktop session we opened earlier, since we no longer have the current machine available from the Internet.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_272.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 10px auto 0px; display: block; padding-right: 0px; border-width: 0px;" title="image" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_234.png" border="0" alt="image" width="400" height="112" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once finished, we can simply remove the &lt;em&gt;C:\Config\profiling.txt&lt;/em&gt; file and Windows Azure will add the machine back to the server pool. Don't forget this as otherwise you'll be paying for the machine without being able to serve the application from it. Reimaging the machine will also add it to the pool again.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=AZzNGG3lmIU:77VTRov6H1k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=AZzNGG3lmIU:77VTRov6H1k:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?i=AZzNGG3lmIU:77VTRov6H1k:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=AZzNGG3lmIU:77VTRov6H1k:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=AZzNGG3lmIU:77VTRov6H1k:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=AZzNGG3lmIU:77VTRov6H1k:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=AZzNGG3lmIU:77VTRov6H1k:Jwdi1b3fU3Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=Jwdi1b3fU3Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/maartenballiauw/~4/AZzNGG3lmIU" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/maartenballiauw/~3/AZzNGG3lmIU/post.aspx</link>
      <comments>http://blog.maartenballiauw.be/post/2013/03/13/Remote-profiling-Windows-Azure-Cloud-Services-with-dotTrace.aspx#comment</comments>
      <guid isPermaLink="false">http://blog.maartenballiauw.be/post.aspx?id=ef23559b-06a0-4a1a-b18b-0ff3aecbab2c</guid>
      <pubDate>Wed, 13 Mar 2013 13:08:00 +0200</pubDate>
      <category>ASP.NET</category>
      <category>C#</category>
      <category>Debugging</category>
      <category>General</category>
      <category>ICT</category>
      <category>Profiling</category>
      <category>Software</category>
      <category>Windows Azure</category>
      <dc:publisher>maartenba</dc:publisher>
      <pingback:server>http://blog.maartenballiauw.be/pingback.axd</pingback:server>
      <pingback:target>http://blog.maartenballiauw.be/post.aspx?id=ef23559b-06a0-4a1a-b18b-0ff3aecbab2c</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://blog.maartenballiauw.be/trackback.axd?id=ef23559b-06a0-4a1a-b18b-0ff3aecbab2c</trackback:ping>
      <wfw:comment>http://blog.maartenballiauw.be/post/2013/03/13/Remote-profiling-Windows-Azure-Cloud-Services-with-dotTrace.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.maartenballiauw.be/syndication.axd?post=ef23559b-06a0-4a1a-b18b-0ff3aecbab2c</wfw:commentRss>
    <feedburner:origLink>http://blog.maartenballiauw.be/post.aspx?id=ef23559b-06a0-4a1a-b18b-0ff3aecbab2c</feedburner:origLink></item>
    <item>
      <title>Custom media types for ASP.NET Web API versioning</title>
      <description>&lt;p&gt;There is a raging discussion on the interwebs on whether to version API&amp;rsquo;s by using their URL or by using a custom media type. Some argue that doing it in the URL breaks REST (since a different URL is a different resource while versions don&amp;rsquo;t necessarily mean a new resource is available). While I still feel good about both approaches, I guess it depends on the domain you are working with.&lt;/p&gt;
&lt;p&gt;But that is not the topic of this talk. I recently found a &lt;a href="http://aspnet.codeplex.com/SourceControl/changeset/view/0e68a22781fd#Samples/WebApi/NamespaceControllerSelector/ReadMe.txt"&gt;sample on CodePlex providing support for routing versioned URL&amp;rsquo;s&lt;/a&gt; to different namespaces. In short, it maps &lt;em&gt;/api/v1/values&lt;/em&gt; to &lt;em&gt;MyApp.V1.Controllers&lt;/em&gt; and /&lt;em&gt;api/v2/values&lt;/em&gt; to &lt;em&gt;MyApp.V2.Controllers&lt;/em&gt;. Great! But that only supports the URL-versioning side of the discussion. Let&amp;rsquo;s implement this sample and build ASP.NET Web API support for versioning an API using custom media types&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Custom Media Types&lt;/h2&gt;
&lt;p&gt;If you have no clue about what I am talking about, no worries. I&amp;rsquo;ll give you a quick primer on this using &lt;a href="http://developer.github.com/v3/media/"&gt;the GitHub API&lt;/a&gt; as an example. Since their API version 3, endpoints for the API (or &amp;ldquo;resource addresses&amp;rdquo;) will no longer change every version of the API. Instead, they will be parsing the &lt;em&gt;Accept&lt;/em&gt; HTTP header to determine the incoming message version and the expected response version.&lt;/p&gt;
&lt;p&gt;Getting a list of repositories from the API? The URL will always be &lt;em&gt;/users/repos&lt;/em&gt;. However different incoming and outgoing responses are possible, varying based on their media types. Want to use the V3 message format in JSON? Use &lt;em&gt;application/vnd.github.v3+json&lt;/em&gt;. Prefer the V3 message format in XML? Use&lt;em&gt; application/vnd.github.v3+xml&lt;/em&gt;. Whenever they update their messages, they can add a new media type such as &lt;em&gt;application/vnd.github.v4&lt;/em&gt; without changing any URL. Nifty trick, aye? Let&amp;rsquo;s do this for our own API.&lt;/p&gt;
&lt;h2&gt;IHttpControllerSelector&lt;/h2&gt;
&lt;p&gt;The &lt;em&gt;IHttpControllerSelector&lt;/em&gt; interface allows you to interfere in selecting the right controller for the current request. This is an ideal location for grabbing all contextual information and providing ASP.NET Web API with a controller based on that context.&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:63070af6-b41b-499f-8fdb-88c3516ade38" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 638px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;  1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; AcceptHeaderControllerSelector &lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;/span&gt;&lt;span style="color: #000000;"&gt; IHttpControllerSelector
&lt;/span&gt;&lt;span style="color: #008080;"&gt;  2&lt;/span&gt; &lt;span style="color: #000000;"&gt;{
&lt;/span&gt;&lt;span style="color: #008080;"&gt;  3&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;const&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; ControllerKey &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;controller&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;  4&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;  5&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; readonly HttpConfiguration _configuration;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;  6&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; readonly Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MediaTypeHeaderValue&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; _namespaceResolver;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;  7&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; readonly Lazy&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Dictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpControllerDescriptor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; _controllers;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;  8&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; readonly HashSet&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; _duplicates;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;  9&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 10&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; AcceptHeaderControllerSelector(HttpConfiguration config&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; Func&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;MediaTypeHeaderValue&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; namespaceResolver)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 11&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 12&lt;/span&gt; &lt;span style="color: #000000;"&gt;        _configuration &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; config;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 13&lt;/span&gt; &lt;span style="color: #000000;"&gt;        _namespaceResolver &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; namespaceResolver;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 14&lt;/span&gt; &lt;span style="color: #000000;"&gt;        _duplicates &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HashSet&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(StringComparer&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;OrdinalIgnoreCase);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 15&lt;/span&gt; &lt;span style="color: #000000;"&gt;        _controllers &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Lazy&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Dictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpControllerDescriptor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(InitializeControllerDictionary);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 16&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 17&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 18&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; Dictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpControllerDescriptor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; InitializeControllerDictionary()
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 19&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 20&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; dictionary &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; Dictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpControllerDescriptor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(StringComparer&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;OrdinalIgnoreCase);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 21&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 22&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Create a lookup table where key is "namespace.controller". The value of "namespace" is the last
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 23&lt;/span&gt; &lt;span style="color: #008000;"&gt;        // segment of the full namespace. For example:
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 24&lt;/span&gt; &lt;span style="color: #008000;"&gt;        // MyApplication.Controllers.V1.ProductsController =&amp;gt; "V1.Products"&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 25&lt;/span&gt; &lt;span style="color: #000000;"&gt;        IAssembliesResolver assembliesResolver &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _configuration&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Services&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;GetAssembliesResolver();
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 26&lt;/span&gt; &lt;span style="color: #000000;"&gt;        IHttpControllerTypeResolver controllersResolver &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _configuration&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Services&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;GetHttpControllerTypeResolver();
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 27&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 28&lt;/span&gt; &lt;span style="color: #000000;"&gt;        ICollection&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Type&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; controllerTypes &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; controllersResolver&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;GetControllerTypes(assembliesResolver);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 29&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 30&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (Type t in controllerTypes)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 31&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 32&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; segments &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; t&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #008080;"&gt;Split&lt;/span&gt;&lt;span style="color: #000000;"&gt;(Type&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Delimiter);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 33&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 34&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; For the dictionary key, strip "Controller" from the end of the type name.
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 35&lt;/span&gt; &lt;span style="color: #008000;"&gt;            // This matches the behavior of DefaultHttpControllerSelector.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 36&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; controllerName &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; t&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Name&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Remove(t&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Name&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; DefaultHttpControllerSelector&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;ControllerSuffix&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Length);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 37&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 38&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #008080;"&gt;key&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;String&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Format(CultureInfo&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;InvariantCulture&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;{0}.{1}&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; segments[segments&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Length &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; controllerName);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 39&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 40&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Check for duplicate keys.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 41&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (dictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Keys&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Contains(&lt;/span&gt;&lt;span style="color: #008080;"&gt;key&lt;/span&gt;&lt;span style="color: #000000;"&gt;))
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 42&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 43&lt;/span&gt; &lt;span style="color: #000000;"&gt;                _duplicates&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Add(&lt;/span&gt;&lt;span style="color: #008080;"&gt;key&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 44&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 45&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 46&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 47&lt;/span&gt; &lt;span style="color: #000000;"&gt;                dictionary[&lt;/span&gt;&lt;span style="color: #008080;"&gt;key&lt;/span&gt;&lt;span style="color: #000000;"&gt;] &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpControllerDescriptor(_configuration&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; t&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Name&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; t);  
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 48&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 49&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 50&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 51&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Remove any duplicates from the dictionary, because these create ambiguous matches. 
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 52&lt;/span&gt; &lt;span style="color: #008000;"&gt;        // For example, "Foo.V1.ProductsController" and "Bar.V1.ProductsController" both map to "v1.products".&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 53&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; s in _duplicates)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 54&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 55&lt;/span&gt; &lt;span style="color: #000000;"&gt;            dictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Remove(s);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 56&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 57&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; dictionary;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 58&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 59&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 60&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Get a value from the route data, if present.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 61&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;private&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;static&lt;/span&gt;&lt;span style="color: #000000;"&gt; T GetRouteVariable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;T&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(IHttpRouteData routeData&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; name)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 62&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 63&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;object&lt;/span&gt;&lt;span style="color: #000000;"&gt; result &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 64&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (routeData&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Values&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;TryGetValue(name&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; out result))
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 65&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 66&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; (T)result;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 67&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 68&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;default&lt;/span&gt;&lt;span style="color: #000000;"&gt;(T);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 69&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 70&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 71&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpControllerDescriptor SelectController(HttpRequestMessage request)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 72&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 73&lt;/span&gt; &lt;span style="color: #000000;"&gt;        IHttpRouteData routeData &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; request&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;GetRouteData();
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 74&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (routeData &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 75&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 76&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpResponseException(HttpStatusCode&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;NotFound);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 77&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 78&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 79&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Get the namespace and controller variables from the route data.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 80&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; namespaceName &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 81&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; accepts in request&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Headers&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Accept)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 82&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 83&lt;/span&gt; &lt;span style="color: #000000;"&gt;            namespaceName &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _namespaceResolver(accepts);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 84&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (namespaceName &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 85&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 86&lt;/span&gt; &lt;span style="color: #000000;"&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 87&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 88&lt;/span&gt; &lt;span style="color: #000000;"&gt;        } 
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 89&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (namespaceName &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 90&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 91&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpResponseException(HttpStatusCode&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;NotFound);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 92&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 93&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 94&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; controllerName &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetRouteVariable&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;(routeData&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; ControllerKey);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 95&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (controllerName &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 96&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 97&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpResponseException(HttpStatusCode&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;NotFound);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 98&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 99&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;100&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Find a matching controller.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;101&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #008080;"&gt;key&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;String&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Format(CultureInfo&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;InvariantCulture&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;{0}.{1}&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; namespaceName&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; controllerName);
&lt;/span&gt;&lt;span style="color: #008080;"&gt;102&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;103&lt;/span&gt; &lt;span style="color: #000000;"&gt;        HttpControllerDescriptor controllerDescriptor;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;104&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (_controllers&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Value&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;TryGetValue(&lt;/span&gt;&lt;span style="color: #008080;"&gt;key&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; out controllerDescriptor))
&lt;/span&gt;&lt;span style="color: #008080;"&gt;105&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;106&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; controllerDescriptor;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;107&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;108&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (_duplicates&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Contains(&lt;/span&gt;&lt;span style="color: #008080;"&gt;key&lt;/span&gt;&lt;span style="color: #000000;"&gt;))
&lt;/span&gt;&lt;span style="color: #008080;"&gt;109&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;110&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpResponseException(
&lt;/span&gt;&lt;span style="color: #008080;"&gt;111&lt;/span&gt; &lt;span style="color: #000000;"&gt;                request&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;CreateErrorResponse(HttpStatusCode&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;InternalServerError&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;112&lt;/span&gt; &lt;span style="color: #000000;"&gt;                &lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;Multiple controllers were found that match this request.&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
&lt;/span&gt;&lt;span style="color: #008080;"&gt;113&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;114&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;115&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;116&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpResponseException(HttpStatusCode&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;NotFound);
&lt;/span&gt;&lt;span style="color: #008080;"&gt;117&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;118&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;119&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;120&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; IDictionary&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpControllerDescriptor&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; GetControllerMapping()
&lt;/span&gt;&lt;span style="color: #008080;"&gt;121&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;122&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; _controllers&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Value;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;123&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;124&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;To be honest, I did not write much code in this. I grabbed the &lt;em&gt;IHttpControllerSelector&lt;/em&gt; implementation &lt;a href="http://aspnet.codeplex.com/SourceControl/changeset/view/0e68a22781fd#Samples/WebApi/NamespaceControllerSelector/ReadMe.txt"&gt;from the sample on CodePlex&lt;/a&gt; and added just these lines to check the &lt;em&gt;Accept&lt;/em&gt; header instead.&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:d37ba3fc-cfe6-4c45-8034-50eb77e30b0b" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 225px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Get the namespace and controller variables from the route data.&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; namespaceName &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; accepts in request&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Headers&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Accept)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;{
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;    namespaceName &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; _namespaceResolver(accepts);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (namespaceName &lt;/span&gt;&lt;span style="color: #000000;"&gt;!=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;break&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;} 
&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (namespaceName &lt;/span&gt;&lt;span style="color: #000000;"&gt;==&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;{
&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;throw&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; HttpResponseException(HttpStatusCode&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;NotFound);
&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;The real logic in finding out the version that is called is delegated to the user of this &lt;em&gt;IHttpControllerSelector&lt;/em&gt;. Let&amp;rsquo;s wire it up!&lt;/p&gt;
&lt;h2&gt;Wiring it up&lt;/h2&gt;
&lt;p&gt;ASP.NET Web API has a lot of &amp;ldquo;plugs&amp;rdquo;, among which there&amp;rsquo;s one where we can plug in our custom &lt;em&gt;IHttpControllerSelector&lt;/em&gt;, Let&amp;rsquo;s override the default one and add our own:&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:4d11e0e2-566f-4552-be5e-ded756e672f1" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 280px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #000000;"&gt;config&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Services&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Replace(typeof(IHttpControllerSelector)&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; AcceptHeaderControllerSelector(config&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; accept &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;foreach&lt;/span&gt;&lt;span style="color: #000000;"&gt; (&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; parameter in accept&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Parameters)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (parameter&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Name&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Equals(&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;version&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; StringComparison&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;InvariantCultureIgnoreCase))
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;                {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;switch&lt;/span&gt;&lt;span style="color: #000000;"&gt; (parameter&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Value)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;1.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;v1&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;                        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;case&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;2.0&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;v2&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;                    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;                }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;            
&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;v2&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; default namespace, return null to throw 404 when namespace not given&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }));&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;As you can see, we can pass in a lambda which gets called with the contents of the &lt;em&gt;Accept&lt;/em&gt; header and must return the namespace obtained from the header. The above example will work when using the version property of a header, e.g.: &lt;em&gt;application/json;version=1.0&lt;/em&gt; and &lt;em&gt;application/json;version=2.0&lt;/em&gt;. The last statement returns &amp;ldquo;v2&amp;rdquo; as the default version when no specific media header is given. Return &lt;em&gt;null&lt;/em&gt; if you want this to result in a &lt;em&gt;404 Page Not Found&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;Using this header scheme is recommended&lt;/span&gt; but of course other options are possible. It&amp;rsquo;s &lt;em&gt;your&lt;/em&gt; lambda!&lt;/p&gt;
&lt;p&gt;Another approach would be going "GitHub style" and use things like &lt;em&gt;application/vnd.api.v1+json &lt;/em&gt;and similar?&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:fd90fa2c-60c4-4be1-9be1-a7bb7139201a" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 168px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #000000;"&gt;config&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Services&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Replace(typeof(IHttpControllerSelector)&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; AcceptHeaderControllerSelector(config&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; accept &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;var&lt;/span&gt;&lt;span style="color: #000000;"&gt; matches &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; Regex&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Match(accept&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;MediaType&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; @&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;application\/vnd.api.(.*)\+.*&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; (matches&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Groups&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #008080;"&gt;Count&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;2&lt;/span&gt;&lt;span style="color: #000000;"&gt;)
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;            {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;                &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; matches&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Groups[&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;]&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;Value;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;            }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;v2&lt;/span&gt;&lt;span style="color: #000000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;; &lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; default namespace, return null to throw 404 when namespace not given&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }));&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;Note that when using the GitHub-style media type, it&amp;rsquo;s best to also configure the default media type formatters to recognize these new types. That way you can even use different media type formats for each API version.&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:b4c5456d-0631-46ac-969b-61656df81650" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 113px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt; Add custom media types as supported to their default formatters&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;config.Formatters.JsonFormatter.SupportedMediaTypes.Add(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MediaTypeWithQualityHeaderValue(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;application/vnd.api.v1+json&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
&lt;/span&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; &lt;span style="color: #000000;"&gt;config.Formatters.JsonFormatter.SupportedMediaTypes.Add(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MediaTypeWithQualityHeaderValue(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;application/vnd.api.v2+json&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
&lt;/span&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt; &lt;span style="color: #000000;"&gt;config.Formatters.XmlFormatter.SupportedMediaTypes.Add(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MediaTypeWithQualityHeaderValue(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;application/vnd.api.v1+xml&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;));
&lt;/span&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt; &lt;span style="color: #000000;"&gt;config.Formatters.XmlFormatter.SupportedMediaTypes.Add(&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; MediaTypeWithQualityHeaderValue(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;application/vnd.api.v2+xml&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;));&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;That&amp;rsquo;s basically it. We can now implement our controllers in different namespaces, like so:&lt;/p&gt;
&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:6fce90c8-cfbd-414e-a2c1-b20bcd45c638" class="wlWriterEditableSmartContent" style="float: none; margin: 0px; display: inline; padding: 0px;"&gt;
&lt;pre style="width: 687px; height: 313px; background-color: white; overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestSelector.Controllers.V1
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;{
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ValuesController : ApiController
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; Get()
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;This is a V1 response.&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;}
&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #0000ff;"&gt;namespace&lt;/span&gt;&lt;span style="color: #000000;"&gt; TestSelector.Controllers.V2
&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;{
&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; ValuesController : ApiController
&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;    {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;string&lt;/span&gt;&lt;span style="color: #000000;"&gt; Get()
&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;        {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt;            &lt;/span&gt;&lt;span style="color: #0000ff;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;This is a V2 response.&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;span style="color: #000000;"&gt;        }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;
&lt;p&gt;When providing different &lt;em&gt;Accept &lt;/em&gt;headers, we now get routed to the correct namespace depending on our custom media type. REST maturity level up!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve issued a pull request on the &lt;a href="http://aspnet.codeplex.com/SourceControl/BrowseLatest"&gt;official samples page&lt;/a&gt;, in the meanwhile here&amp;rsquo;s the download: &lt;a href="http://blog.maartenballiauw.be/file.axd?file=2013%2f3%2fAcceptHeaderControllerSelector.zip"&gt;AcceptHeaderControllerSelector.zip (238.43 kb)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;[edit]&lt;/strong&gt; there's a project on GitHub containing other implementations as well, check &lt;a rel="nofollow" href="http://github.com/Sebazzz/SDammann.WebApi.Versioning"&gt;http://github.com/Sebazzz/SDammann.WebApi.Versioning&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=2GNTL001jTI:To4Fs2NJsEE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=2GNTL001jTI:To4Fs2NJsEE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?i=2GNTL001jTI:To4Fs2NJsEE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=2GNTL001jTI:To4Fs2NJsEE:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=2GNTL001jTI:To4Fs2NJsEE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=2GNTL001jTI:To4Fs2NJsEE:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=2GNTL001jTI:To4Fs2NJsEE:Jwdi1b3fU3Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=Jwdi1b3fU3Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/maartenballiauw/~4/2GNTL001jTI" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/maartenballiauw/~3/2GNTL001jTI/post.aspx</link>
      <comments>http://blog.maartenballiauw.be/post/2013/03/08/Custom-media-types-for-ASPNET-Web-API-versioning.aspx#comment</comments>
      <guid isPermaLink="false">http://blog.maartenballiauw.be/post.aspx?id=855e3520-a47d-45ed-98a0-4e0c931f3867</guid>
      <pubDate>Fri, 08 Mar 2013 12:25:00 +0200</pubDate>
      <category>ASP.NET</category>
      <category>C#</category>
      <category>General</category>
      <category>ICT</category>
      <category>WebAPI</category>
      <dc:publisher>maartenba</dc:publisher>
      <pingback:server>http://blog.maartenballiauw.be/pingback.axd</pingback:server>
      <pingback:target>http://blog.maartenballiauw.be/post.aspx?id=855e3520-a47d-45ed-98a0-4e0c931f3867</pingback:target>
      <slash:comments>9</slash:comments>
      <trackback:ping>http://blog.maartenballiauw.be/trackback.axd?id=855e3520-a47d-45ed-98a0-4e0c931f3867</trackback:ping>
      <wfw:comment>http://blog.maartenballiauw.be/post/2013/03/08/Custom-media-types-for-ASPNET-Web-API-versioning.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.maartenballiauw.be/syndication.axd?post=855e3520-a47d-45ed-98a0-4e0c931f3867</wfw:commentRss>
    <feedburner:origLink>http://blog.maartenballiauw.be/post.aspx?id=855e3520-a47d-45ed-98a0-4e0c931f3867</feedburner:origLink></item>
    <item>
      <title>Taking over the @msdnbelux Twitter account</title>
      <description>&lt;p&gt;Just a quick post to let you know I&amp;rsquo;ll be taking over the &lt;a href="http://www.twitter.com/msdnbelux"&gt;@msdnbelux&lt;/a&gt; Twitter account for the next two weeks. This is the official Twitter account for MSDN BeLux. It&amp;rsquo;s not hacked, I did not steal the password: they gave it to me!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_260.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin: 5px auto; display: block; padding-right: 0px; border: 0px;" title="image" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_222.png" border="0" alt="image" width="484" height="336" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The best thing about this takeover is that there are no constraints: I can tweet whatever I want to tweet! So far it's been fun to do, I've seen a lot of reactions on my tweets as well. Let me know how I do! Who knows, I might just change the password and keep this account for myself after these two weeks :-)&lt;/p&gt;
&lt;p&gt;Follow &lt;a href="https://twitter.com/msdnbelux"&gt;@msdnbelux&lt;/a&gt; and I&amp;rsquo;ll provide you with great ASP.NET MVC, ASP.NET Web API, JavaScript and Windows Azure related content.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=Job2KYwcZSs:W4nxy_znP_8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=Job2KYwcZSs:W4nxy_znP_8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?i=Job2KYwcZSs:W4nxy_znP_8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=Job2KYwcZSs:W4nxy_znP_8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=Job2KYwcZSs:W4nxy_znP_8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=Job2KYwcZSs:W4nxy_znP_8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=Job2KYwcZSs:W4nxy_znP_8:Jwdi1b3fU3Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=Jwdi1b3fU3Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/maartenballiauw/~4/Job2KYwcZSs" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/maartenballiauw/~3/Job2KYwcZSs/post.aspx</link>
      <comments>http://blog.maartenballiauw.be/post/2013/02/27/Taking-over-the-msdnbelux-Twitter-account.aspx#comment</comments>
      <guid isPermaLink="false">http://blog.maartenballiauw.be/post.aspx?id=be4ab8cb-f5ee-4d00-8808-4b8265e69135</guid>
      <pubDate>Wed, 27 Feb 2013 11:59:00 +0200</pubDate>
      <category>General</category>
      <category>ICT</category>
      <category>Personal</category>
      <category>Windows Azure</category>
      <dc:publisher>maartenba</dc:publisher>
      <pingback:server>http://blog.maartenballiauw.be/pingback.axd</pingback:server>
      <pingback:target>http://blog.maartenballiauw.be/post.aspx?id=be4ab8cb-f5ee-4d00-8808-4b8265e69135</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.maartenballiauw.be/trackback.axd?id=be4ab8cb-f5ee-4d00-8808-4b8265e69135</trackback:ping>
      <wfw:comment>http://blog.maartenballiauw.be/post/2013/02/27/Taking-over-the-msdnbelux-Twitter-account.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.maartenballiauw.be/syndication.axd?post=be4ab8cb-f5ee-4d00-8808-4b8265e69135</wfw:commentRss>
    <feedburner:origLink>http://blog.maartenballiauw.be/post.aspx?id=be4ab8cb-f5ee-4d00-8808-4b8265e69135</feedburner:origLink></item>
    <item>
      <title>Working with Windows Azure SQL Database in PhpStorm</title>
      <description>&lt;p&gt;&lt;em&gt;Disclaimer: My job at &lt;/em&gt;&lt;a href="http://www.jetbrains.com"&gt;&lt;em&gt;JetBrains&lt;/em&gt;&lt;/a&gt;&lt;em&gt; holds a lot of “exploration of tools”. From time to time I discover things I personally find really cool and blog about those on the JetBrains blogs. If it relates to Windows Azure, I&amp;#160; typically cross-post on my personal blog.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image002_4.jpg"&gt;&lt;img title="clip_image002" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: right; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="clip_image002" align="right" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image002_thumb_3.jpg" width="190" height="92" /&gt;&lt;/a&gt;PhpStorm provides us the possibility to connect to Windows Azure SQL Database right from within the IDE. In this post, we’ll explore several options that are available for working with Windows Azure SQL Database (or database systems like SQL Server, MySQL, PostgreSQL or Oracle, for that matter):&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Setting up a database connection&lt;/li&gt;    &lt;li&gt;Creating a table&lt;/li&gt;    &lt;li&gt;Inserting and updating data&lt;/li&gt;    &lt;li&gt;Using the database console&lt;/li&gt;    &lt;li&gt;Generating a database diagram&lt;/li&gt;    &lt;li&gt;Database refactoring&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you are familiar with Windows Azure SQL Database, make sure to &lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/ee621783.aspx"&gt;configure the database firewall&lt;/a&gt; correctly so you can connect to it from your current machine.&lt;/p&gt;  &lt;h4&gt;&lt;a name="h.ncogzmk7ux8c"&gt;&lt;/a&gt;Setting up a database connection&lt;/h4&gt;  &lt;p&gt;Database support can be found on the right-hand side of the IDE or by using the &lt;b&gt;&lt;i&gt;Ctrl+Alt+A (Cmd+Alt+A on Mac)&lt;/i&gt;&lt;/b&gt;&lt;i&gt; &lt;/i&gt;and searching for “Database”.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image004_2.jpg"&gt;&lt;img title="clip_image004" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image004" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image004_thumb_2.jpg" width="484" height="132" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Opening the database pane, we can create a new connection or &lt;i&gt;Data Source&lt;/i&gt;. We’ll have to specify the JDBC database driver to be used to connect to our database. Since Windows Azure SQL Database is just “SQL Server” in essence, we can use the &lt;i&gt;SQL Server &lt;/i&gt;driver available in the list of drivers. PhpStorm doesn’t ship these drivers but a simple click (on “Click here”) fetches the correct JDBC driver from the Internet.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image006_2.jpg"&gt;&lt;img title="clip_image006" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image006" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image006_thumb_2.jpg" width="484" height="230" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Next, we’ll have to enter our connection details. As the JDBC driver class, select the &lt;i&gt;com.microsoft.sqlserver.jdbc&lt;/i&gt; driver. The Database URL should be a connection string to our SQL Database and typically comes in the following form:&lt;/p&gt;  &lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:f36960c5-2587-4109-8588-a165449f6ee5" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 34px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;jdbc&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;/span&gt;&lt;span style="color: #000000;"&gt;sqlserver&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;&amp;lt;servername&amp;gt;.database.windows.net;database=&amp;lt;databasename&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;The username to use comes in a different form. Due to a protocol change that was required for Windows Azure SQL Database, we have to suffix the username with the server name.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image007.gif"&gt;&lt;img title="clip_image007" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image007" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image007_thumb.gif" width="484" height="126" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After filling out the necessary information, we can use the &lt;i&gt;Test Connection&lt;/i&gt; button to test the database connection.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image009.jpg"&gt;&lt;img title="clip_image009" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image009" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image009_thumb.jpg" width="376" height="205" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! Our database connection is a fact and we can store it by closing the Data Source dialog using the &lt;i&gt;Ok&lt;/i&gt; button.&lt;/p&gt;

&lt;h4&gt;&lt;a name="h.3apfo6u5f13u"&gt;&lt;/a&gt;Creating a table&lt;/h4&gt;

&lt;p&gt;If we right click a schema discovered in our Data Source, we can use the &lt;b&gt;&lt;i&gt;New | Table&lt;/i&gt;&lt;/b&gt; menu item to create a table.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image011.jpg"&gt;&lt;img title="clip_image011" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image011" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image011_thumb.jpg" width="347" height="98" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can use the Create New Table dialog to define columns on our to-be-created table. PhpStorm provides us with a user interface which allows us to graphically specify columns and generates the DDL for us.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image013.jpg"&gt;&lt;img title="clip_image013" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image013" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image013_thumb.jpg" width="484" height="682" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking &lt;i&gt;Ok&lt;/i&gt; will close the dialog and create the table for us. We can now right-click our table and modify existing columns or add additional columns and generate DDL which alters the table.&lt;/p&gt;

&lt;h4&gt;&lt;a name="h.qguqoz1mxdaf"&gt;&lt;/a&gt;Inserting and updating data&lt;/h4&gt;

&lt;p&gt;After creating a table, we can insert data (or update data from an existing table). Upon connecting to the database, PhpStorm will display a list of all tables and their columns. We can select a table and press &lt;b&gt;&lt;i&gt;F4&lt;/i&gt;&lt;/b&gt; (or right-click and use the &lt;i&gt;Table Editor&lt;/i&gt; context menu). &lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image015.jpg"&gt;&lt;img title="clip_image015" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image015" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image015_thumb.jpg" width="484" height="357" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can add new rows and/or edit existing rows by using the &lt;b&gt;&lt;i&gt;+ &lt;/i&gt;&lt;/b&gt;and &lt;b&gt;&lt;i&gt;-&lt;/i&gt;&lt;/b&gt; buttons in the toolbar. By default, auto-commit is enabled and changes are committed automatically to the database. We can disable this option and manually commit and rollback any changes that have been made in the table editor.&lt;/p&gt;

&lt;h4&gt;&lt;a name="h.ljaqg6wifjae"&gt;&lt;/a&gt;Using the database console&lt;/h4&gt;

&lt;p&gt;Sometimes there is no better tool than a database console. We can bring up the Console by right-clicking a table and selecting the &lt;b&gt;&lt;i&gt;Console&lt;/i&gt;&lt;/b&gt; menu item or simply by pressing &lt;b&gt;&lt;i&gt;Ctrl+Shift+F10 (Cmd+Shift+F10 on Mac)&lt;/i&gt;&lt;/b&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image017.jpg"&gt;&lt;img title="clip_image017" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image017" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image017_thumb.jpg" width="484" height="357" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can enter any SQL statement in the console and run it against our database. As you can see from the screenshot above, we even get autocompletion on table names and column names!&lt;/p&gt;

&lt;h4&gt;&lt;a name="h.6f86lf4sf5jz"&gt;&lt;/a&gt;Generating a database diagram&lt;/h4&gt;

&lt;p&gt;If we have multiple tables with foreign keys between them, we can easily generate a database diagram by selecting the tables to be included in the diagram and selecting &lt;b&gt;&lt;i&gt;Diagrams | Show Visualization...&lt;/i&gt;&lt;/b&gt; from the context menu or using the &lt;b&gt;&lt;i&gt;Ctrl+Alt+Shift+U (Cmd+Alt+Shift+U on Mac)&lt;/i&gt;&lt;/b&gt;. PhpStorm will then generate a database diagram for these tables, displaying how they relate to each other.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image019.jpg"&gt;&lt;img title="clip_image019" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image019" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image019_thumb.jpg" width="484" height="357" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;&lt;a name="h.lfob9gdcz8mu"&gt;&lt;/a&gt;Database refactoring&lt;/h4&gt;

&lt;p&gt;Renaming a table or column often is tedious. PhpStorm includes a Rename refactoring (&lt;b&gt;&lt;i&gt;Shift-F6&lt;/i&gt;&lt;/b&gt;) which generates the required SQL code for renaming tables or columns.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image021.jpg"&gt;&lt;img title="clip_image021" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; border-left: 0px; display: block; padding-right: 0px; margin-right: auto" border="0" alt="clip_image021" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image021_thumb.jpg" width="411" height="305" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we’ve seen in this post, working with Windows Azure SQL Database is pretty simple from within PhpStorm using the built-in database support.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=UTTcBGgPzLg:cptskfmzyeM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=UTTcBGgPzLg:cptskfmzyeM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?i=UTTcBGgPzLg:cptskfmzyeM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=UTTcBGgPzLg:cptskfmzyeM:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=UTTcBGgPzLg:cptskfmzyeM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=UTTcBGgPzLg:cptskfmzyeM:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=UTTcBGgPzLg:cptskfmzyeM:Jwdi1b3fU3Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=Jwdi1b3fU3Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/maartenballiauw/~4/UTTcBGgPzLg" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/maartenballiauw/~3/UTTcBGgPzLg/post.aspx</link>
      <comments>http://blog.maartenballiauw.be/post/2013/02/25/Working-with-Windows-Azure-SQL-Database-in-PhpStorm.aspx#comment</comments>
      <guid isPermaLink="false">http://blog.maartenballiauw.be/post.aspx?id=05166b4d-15a8-484d-91c9-7676e0dda42b</guid>
      <pubDate>Mon, 25 Feb 2013 10:01:19 +0200</pubDate>
      <category>General</category>
      <category>ICT</category>
      <category>SQL Azure</category>
      <category>Windows Azure</category>
      <category>PHP</category>
      <category>Software</category>
      <dc:publisher>maartenba</dc:publisher>
      <pingback:server>http://blog.maartenballiauw.be/pingback.axd</pingback:server>
      <pingback:target>http://blog.maartenballiauw.be/post.aspx?id=05166b4d-15a8-484d-91c9-7676e0dda42b</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://blog.maartenballiauw.be/trackback.axd?id=05166b4d-15a8-484d-91c9-7676e0dda42b</trackback:ping>
      <wfw:comment>http://blog.maartenballiauw.be/post/2013/02/25/Working-with-Windows-Azure-SQL-Database-in-PhpStorm.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.maartenballiauw.be/syndication.axd?post=05166b4d-15a8-484d-91c9-7676e0dda42b</wfw:commentRss>
    <feedburner:origLink>http://blog.maartenballiauw.be/post.aspx?id=05166b4d-15a8-484d-91c9-7676e0dda42b</feedburner:origLink></item>
    <item>
      <title>Global Windows Azure Bootcamp - april 27th</title>
      <description>&lt;p&gt;On April 27th, 2013, you&amp;rsquo;ll have the ability to join a Windows Azure Bootcamp on a location close to you. We&amp;rsquo;ve started this with the idea of maybe having 10 or 15 locations world wide. We were wrong. Here&amp;rsquo;s what happened:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_259.png"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="Much ocations for our bootcamp!" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_221.png" border="0" alt="Much ocations for our bootcamp!" width="484" height="238" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In short: we now have over 50 locations available where a bootcamp will be organized! This one day deep dive class will get you up to speed on developing for Windows Azure. The class includes a trainer with deep real world experience with Windows Azure, as well as a series of labs so you can practice what you just learned. It&amp;rsquo;s free, so &lt;a href="http://globalwindowsazure.azurewebsites.net/?page_id=151"&gt;find your location&lt;/a&gt; and join the fun!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=tRv71XgqK9Q:Z_pwS6xw9Ws:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=tRv71XgqK9Q:Z_pwS6xw9Ws:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?i=tRv71XgqK9Q:Z_pwS6xw9Ws:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=tRv71XgqK9Q:Z_pwS6xw9Ws:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=tRv71XgqK9Q:Z_pwS6xw9Ws:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=tRv71XgqK9Q:Z_pwS6xw9Ws:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=tRv71XgqK9Q:Z_pwS6xw9Ws:Jwdi1b3fU3Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=Jwdi1b3fU3Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/maartenballiauw/~4/tRv71XgqK9Q" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/maartenballiauw/~3/tRv71XgqK9Q/post.aspx</link>
      <comments>http://blog.maartenballiauw.be/post/2013/02/18/Global-Windows-Azure-Bootcamp-april-27th.aspx#comment</comments>
      <guid isPermaLink="false">http://blog.maartenballiauw.be/post.aspx?id=9a5a4961-0a06-47d3-adaa-18ec5eab00f7</guid>
      <pubDate>Mon, 18 Feb 2013 17:26:00 +0200</pubDate>
      <category>C#</category>
      <category>Events</category>
      <category>General</category>
      <category>SQL Azure</category>
      <category>Windows Azure</category>
      <dc:publisher>maartenba</dc:publisher>
      <pingback:server>http://blog.maartenballiauw.be/pingback.axd</pingback:server>
      <pingback:target>http://blog.maartenballiauw.be/post.aspx?id=9a5a4961-0a06-47d3-adaa-18ec5eab00f7</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://blog.maartenballiauw.be/trackback.axd?id=9a5a4961-0a06-47d3-adaa-18ec5eab00f7</trackback:ping>
      <wfw:comment>http://blog.maartenballiauw.be/post/2013/02/18/Global-Windows-Azure-Bootcamp-april-27th.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.maartenballiauw.be/syndication.axd?post=9a5a4961-0a06-47d3-adaa-18ec5eab00f7</wfw:commentRss>
    <feedburner:origLink>http://blog.maartenballiauw.be/post.aspx?id=9a5a4961-0a06-47d3-adaa-18ec5eab00f7</feedburner:origLink></item>
    <item>
      <title>Running unit tests when deploying to Windows Azure Web Sites</title>
      <description>&lt;p&gt;When deploying an application to Windows Azure Web Sites, a number of deployment steps are executed. For .NET projects, msbuild is triggered. For node.js applications, a list of dependencies is restored. For PHP applications, files are copied from source control to the actual web root which is served publicly. Wouldn’t it be cool if Windows Azure Web Sites refused to deploy fresh source code whenever unit tests fail? In this post, I’ll show you how.&lt;/p&gt;  &lt;p&gt;&lt;u&gt;Disclaimer:&lt;/u&gt;&amp;#160; I’m using PHP and PHPUnit here but the same approach can be used for node.js. .NET is a bit harder since most test runners out there are not supported by the Windows Azure Web Sites sandbox. I’m confident however that in the near future this issue will be resolved and the same technique can be used for .NET applications.&lt;/p&gt;  &lt;h2&gt;Our sample application&lt;/h2&gt;  &lt;p&gt;First of all, let’s create a simple application. Here’s a very simple one using the &lt;a href="http://silex.sensiolabs.org/"&gt;Silex&lt;/a&gt; framework which is similar to frameworks like &lt;a href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt; and &lt;a href="http://www.nancyfx.org/"&gt;Nancy&lt;/a&gt;.&lt;/p&gt;  &lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:5539d472-8bdc-4462-a580-86fdb46a9ec9" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 163px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #000000;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt;php
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;require_once&lt;/span&gt;&lt;span style="color: #000000;"&gt;(__DIR__ &lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;/../vendor/autoload.php&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$app&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;new&lt;/span&gt;&lt;span style="color: #000000;"&gt; \Silex\Application();
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$app&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;get(&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;,&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt; (\Silex\Application &lt;/span&gt;&lt;span style="color: #800080;"&gt;$app&lt;/span&gt;&lt;span style="color: #000000;"&gt;)  {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;return&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;Hello, world!&lt;/span&gt;&lt;span style="color: #000000;"&gt;'&lt;/span&gt;&lt;span style="color: #000000;"&gt;;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;});
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$app&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;run();&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;Next, we can create some unit tests for this application. Since our app itself isn’t that massive to test, let’s create some dummy tests instead:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:d3e438a6-422e-4bf8-a262-cbe0151ff600" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 273px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #000000;"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt;php
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #000000;"&gt;namespace Jb\Tests;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;class&lt;/span&gt;&lt;span style="color: #000000;"&gt; SampleTest
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;extends&lt;/span&gt;&lt;span style="color: #000000;"&gt; \PHPUnit_Framework_TestCase {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt; testFoo() {
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #800080;"&gt;$this&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;assertTrue(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt; testBar() {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #800080;"&gt;$this&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;assertTrue(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;public&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;function&lt;/span&gt;&lt;span style="color: #000000;"&gt; testBar2() {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;        &lt;/span&gt;&lt;span style="color: #800080;"&gt;$this&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;assertTrue(&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;true&lt;/span&gt;&lt;span style="color: #000000;"&gt;);
&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;    }
&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;As we can see from our IDE, the three unit tests run perfectly fine.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_254.png"&gt;&lt;img title="Running PHPUnit in PhpStorm" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin: 5px auto; border-left: 0px; display: block; padding-right: 0px" border="0" alt="Running PHPUnit in PhpStorm" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_216.png" width="480" height="261" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s see if we can hook them up to Windows Azure Web Sites…&lt;/p&gt;

&lt;h2&gt;Creating a Windows Azure Web Sites deployment script&lt;/h2&gt;

&lt;p&gt;Windows Azure Web Sites allows us to customize deployment. Using the &lt;a href="http://www.windowsazure.com/en-us/manage/linux/other-resources/command-line-tools/"&gt;azure-cli&lt;/a&gt; tools we can issue the following command:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:fe4a16d9-425d-4284-a4ac-62876dbc7695" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 18px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;azure site deploymentscript&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;As you can see from the following screenshot, this command allows us to specify some additional options, such as specifying the project type (ASP.NET, PHP, node.js, …) or the script type (batch or bash).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_255.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin: 5px auto; border-left: 0px; display: block; padding-right: 0px" border="0" alt="image" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_217.png" width="484" height="380" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Running this command does two things: it creates a &lt;em&gt;.deployment &lt;/em&gt;file which tells Windows Azure Web Sites which command should be run during the deployment process and a &lt;em&gt;deploy.cmd&lt;/em&gt; (or &lt;em&gt;deploy.sh&lt;/em&gt; if you’ve opted for a bash script) which contains the entire deployment process. Let’s first look at the &lt;em&gt;.deployment&lt;/em&gt; file:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:8dad21fc-d9ce-4f6c-8bfd-a3ab1ddad6e3" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 31px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #000000;"&gt;[config]
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;command &lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt; bash deploy&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;sh&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;This is a very simple file which tells Windows Azure Web Sites to invoke the &lt;em&gt;deploy.sh&lt;/em&gt; script using &lt;em&gt;bash&lt;/em&gt; as the shell. The default &lt;em&gt;deploy.sh&lt;/em&gt; will look like this:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:6c7ec3e7-5f30-463b-9470-bde6fa9b3978" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 273px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;!/bin/bash&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; ----------------------&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; KUDU Deployment Script&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; ----------------------&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; Helpers&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; -------&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;exitWithMessageOnError () {
&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; [ &lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt; $&lt;/span&gt;&lt;span style="color: #000000;"&gt;?&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;eq &lt;/span&gt;&lt;span style="color: #000000;"&gt;0&lt;/span&gt;&lt;span style="color: #000000;"&gt; ]; then
&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;An error has occured during web site deployment.&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; $&lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; &lt;span style="color: #000000;"&gt;    &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;exit&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;1&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;span style="color: #000000;"&gt;  fi
&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; &lt;span style="color: #000000;"&gt;}
&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; Prerequisites&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; -------------&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; Verify node.js installed&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;where node &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;amp;&amp;gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;dev&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;null&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; &lt;span style="color: #000000;"&gt;exitWithMessageOnError &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Missing node.js executable, please install node.js, if already installed make sure it can be reached from current environment.&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; Setup&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; -----&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; &lt;span style="color: #000000;"&gt;SCRIPT_DIR&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;$( cd -P &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;$( &lt;/span&gt;&lt;span style="color: #008080;"&gt;dirname&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;${BASH_SOURCE[0]}&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; )&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &amp;amp;&amp;amp; pwd )&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; &lt;span style="color: #000000;"&gt;ARTIFACTS&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800080;"&gt;$SCRIPT_DIR&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;artifacts
&lt;/span&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; [[ &lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;n &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$DEPLOYMENT_SOURCE&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ]]; then
&lt;/span&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt; &lt;span style="color: #000000;"&gt;  DEPLOYMENT_SOURCE&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800080;"&gt;$SCRIPT_DIR&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; &lt;span style="color: #000000;"&gt;fi
&lt;/span&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; [[ &lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;n &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$NEXT_MANIFEST_PATH&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ]]; then
&lt;/span&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; &lt;span style="color: #000000;"&gt;  NEXT_MANIFEST_PATH&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800080;"&gt;$ARTIFACTS&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;manifest
&lt;/span&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; [[ &lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;n &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$PREVIOUS_MANIFEST_PATH&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ]]; then
&lt;/span&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; &lt;span style="color: #000000;"&gt;    PREVIOUS_MANIFEST_PATH&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800080;"&gt;$NEXT_MANIFEST_PATH&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; &lt;span style="color: #000000;"&gt;  fi
&lt;/span&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; &lt;span style="color: #000000;"&gt;fi
&lt;/span&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; [[ &lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;n &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$KUDU_SYNC_COMMAND&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ]]; then
&lt;/span&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; Install kudu sync&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Installing Kudu Sync
&lt;/span&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt; &lt;span style="color: #000000;"&gt;  npm install kudusync &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;g &lt;/span&gt;&lt;span style="color: #000000;"&gt;--&lt;/span&gt;&lt;span style="color: #000000;"&gt;silent
&lt;/span&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt; &lt;span style="color: #000000;"&gt;  exitWithMessageOnError &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;npm failed&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt; &lt;span style="color: #000000;"&gt;  KUDU_SYNC_COMMAND&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;kuduSync&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt; &lt;span style="color: #000000;"&gt;fi
&lt;/span&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;if&lt;/span&gt;&lt;span style="color: #000000;"&gt; [[ &lt;/span&gt;&lt;span style="color: #000000;"&gt;!&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;n &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$DEPLOYMENT_TARGET&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; ]]; then
&lt;/span&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt; &lt;span style="color: #000000;"&gt;  DEPLOYMENT_TARGET&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #800080;"&gt;$ARTIFACTS&lt;/span&gt;&lt;span style="color: #000000;"&gt;/&lt;/span&gt;&lt;span style="color: #000000;"&gt;wwwroot
&lt;/span&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;else&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt; &lt;span style="color: #000000;"&gt;  &lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; In case we are running on kudu service this is the correct location of kuduSync&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;  KUDU_SYNC_COMMAND&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$APPDATA&lt;/span&gt;&lt;span style="color: #000000;"&gt;\\npm\\node_modules\\kuduSync\\bin\\kuduSync&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt; &lt;span style="color: #000000;"&gt;fi
&lt;/span&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;#################################################################################################################################&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; Deployment&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; ----------&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Handling Basic Web Site deployment&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; 1. KuduSync&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Kudu Sync from &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$DEPLOYMENT_SOURCE&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; to &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$DEPLOYMENT_TARGET&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$KUDU_SYNC_COMMAND&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;q &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;f &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$DEPLOYMENT_SOURCE&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;t &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$DEPLOYMENT_TARGET&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;n &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$NEXT_MANIFEST_PATH&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;p &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$PREVIOUS_MANIFEST_PATH&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;i &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;.git;.deployment;deploy.sh&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;68&lt;/span&gt; &lt;span style="color: #000000;"&gt;exitWithMessageOnError &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Kudu Sync failed&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;69&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;70&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;#################################################################################################################################&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;71&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;72&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;Finished successfully.&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;73&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;This script does two things: setup a bunch of environment variables so our script has all the paths to the source code repository, the target web site root and some well-known commands, Next, it runs the &lt;em&gt;&lt;a href="https://github.com/projectkudu/KuduSync"&gt;KuduSync&lt;/a&gt;&lt;/em&gt; executable, a helper which copies files from the source code repository to the web site root using an optimized algorithm which only copies files that have been modified. For .NET, there would be a third action which is done: running msbuild to compile sources into binaries.&lt;/p&gt;

&lt;p&gt;Right before the part that reads&lt;em&gt; # Deployment&lt;/em&gt;, we can add some additional steps for running unit tests. We can invoke the &lt;em&gt;php.exe&lt;/em&gt; executable (located on the D:\ drive in Windows Azure Web Sites) and run &lt;em&gt;phpunit.php&lt;/em&gt; passing in the path to the test configuration file:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:a6598b78-8739-4e90-99e3-3d6f2550e63a" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 189px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt;#################################################################################################################################&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; Testing&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; &lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; -------&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Running PHPUnit tests&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; &lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #008000;"&gt;#&lt;/span&gt;&lt;span style="color: #008000;"&gt; 1. PHPUnit&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;D:\Program Files (x86)\PHP\v5.4\php.exe&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;d auto_prepend_file&lt;/span&gt;&lt;span style="color: #000000;"&gt;=&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$DEPLOYMENT_SOURCE&lt;/span&gt;&lt;span style="color: #000000;"&gt;\\vendor\\autoload.php&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$DEPLOYMENT_SOURCE&lt;/span&gt;&lt;span style="color: #000000;"&gt;\\vendor\\phpunit\\phpunit\\phpunit.php&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; &lt;/span&gt;&lt;span style="color: #000000;"&gt;--&lt;/span&gt;&lt;span style="color: #000000;"&gt;configuration &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$DEPLOYMENT_SOURCE&lt;/span&gt;&lt;span style="color: #000000;"&gt;\\app\\phpunit.xml&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;span style="color: #000000;"&gt;exitWithMessageOnError &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;PHPUnit tests failed&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;p&gt;On a side note, we can also run other commands like issuing a &lt;em&gt;composer update&lt;/em&gt;, similar to NuGet package restore in the .NET world:&lt;/p&gt;

&lt;div id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:74f06cdc-cf42-4e69-a00b-8bf75af234d5" class="wlWriterEditableSmartContent" style="float: none; padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px"&gt;&lt;pre style=" width: 687px; height: 122px;background-color:White;overflow: auto;"&gt;&lt;div&gt;&lt;!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt;&lt;span style="color: #008080;"&gt;1&lt;/span&gt; &lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Download composer&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;2&lt;/span&gt; &lt;span style="color: #000000;"&gt;curl &lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;O https&lt;/span&gt;&lt;span style="color: #000000;"&gt;:&lt;/span&gt;&lt;span style="color: #008000;"&gt;//&lt;/span&gt;&lt;span style="color: #008000;"&gt;getcomposer.org/composer.phar &amp;gt; /dev/null&lt;/span&gt;&lt;span style="color: #008000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;3&lt;/span&gt; &lt;span style="color: #008000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;4&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #0000FF;"&gt;echo&lt;/span&gt;&lt;span style="color: #000000;"&gt; Run composer update&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;5&lt;/span&gt; &lt;span style="color: #000000;"&gt;cd &lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #800080;"&gt;$DEPLOYMENT_SOURCE&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;
&lt;/span&gt;&lt;span style="color: #008080;"&gt;6&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt;D:\Program Files (x86)\PHP\v5.4\php.exe&lt;/span&gt;&lt;span style="color: #000000;"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000;"&gt; composer&lt;/span&gt;&lt;span style="color: #000000;"&gt;.&lt;/span&gt;&lt;span style="color: #000000;"&gt;phar update &lt;/span&gt;&lt;span style="color: #000000;"&gt;--&lt;/span&gt;&lt;span style="color: #000000;"&gt;optimize&lt;/span&gt;&lt;span style="color: #000000;"&gt;-&lt;/span&gt;&lt;span style="color: #000000;"&gt;autoloader
&lt;/span&gt;&lt;span style="color: #008080;"&gt;7&lt;/span&gt; &lt;span style="color: #000000;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;&lt;!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --&gt;&lt;/div&gt;

&lt;h2&gt;Putting our deployment script to the test&lt;/h2&gt;

&lt;p&gt;All that’s left to do now is commit and push our changes to Windows Azure Web Sites. If everything goes right, the output for the &lt;em&gt;git push&lt;/em&gt; command should contain details of running our unit tests:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_256.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin: 5px auto; border-left: 0px; display: block; padding-right: 0px" border="0" alt="image" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_218.png" width="480" height="362" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s what happens when a test fails:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_257.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin: 5px auto; border-left: 0px; display: block; padding-right: 0px" border="0" alt="image" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_219.png" width="480" height="460" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And even better, the Windows Azure Web Sites portal shows us that the latest sources were commited to the git repository but not deployed because tests failed:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=image_258.png"&gt;&lt;img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; float: none; padding-top: 0px; padding-left: 0px; margin: 5px auto; border-left: 0px; display: block; padding-right: 0px" border="0" alt="image" src="http://blog.maartenballiauw.be/image.axd?picture=image_thumb_220.png" width="480" height="192" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, using deployment scripts we can customize deployment on Windows Azure Web Sites to fit our needs. We can run unit tests, fetch source code from a different location and so on. Enjoy!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=eWPiQDzJCYk:lapT57-iLXY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=eWPiQDzJCYk:lapT57-iLXY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?i=eWPiQDzJCYk:lapT57-iLXY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=eWPiQDzJCYk:lapT57-iLXY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=eWPiQDzJCYk:lapT57-iLXY:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=eWPiQDzJCYk:lapT57-iLXY:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=eWPiQDzJCYk:lapT57-iLXY:Jwdi1b3fU3Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=Jwdi1b3fU3Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/maartenballiauw/~4/eWPiQDzJCYk" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/maartenballiauw/~3/eWPiQDzJCYk/post.aspx</link>
      <comments>http://blog.maartenballiauw.be/post/2013/01/30/Running-unit-tests-when-deploying-to-Windows-Azure-Web-Sites.aspx#comment</comments>
      <guid isPermaLink="false">http://blog.maartenballiauw.be/post.aspx?id=f0b23168-62bc-4c9d-a410-f9d8709d3b80</guid>
      <pubDate>Wed, 30 Jan 2013 10:18:56 +0200</pubDate>
      <category>C#</category>
      <category>ASP.NET</category>
      <category>General</category>
      <category>ICT</category>
      <category>PHP</category>
      <category>Windows Azure</category>
      <dc:publisher>maartenba</dc:publisher>
      <pingback:server>http://blog.maartenballiauw.be/pingback.axd</pingback:server>
      <pingback:target>http://blog.maartenballiauw.be/post.aspx?id=f0b23168-62bc-4c9d-a410-f9d8709d3b80</pingback:target>
      <slash:comments>5</slash:comments>
      <trackback:ping>http://blog.maartenballiauw.be/trackback.axd?id=f0b23168-62bc-4c9d-a410-f9d8709d3b80</trackback:ping>
      <wfw:comment>http://blog.maartenballiauw.be/post/2013/01/30/Running-unit-tests-when-deploying-to-Windows-Azure-Web-Sites.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.maartenballiauw.be/syndication.axd?post=f0b23168-62bc-4c9d-a410-f9d8709d3b80</wfw:commentRss>
    <feedburner:origLink>http://blog.maartenballiauw.be/post.aspx?id=f0b23168-62bc-4c9d-a410-f9d8709d3b80</feedburner:origLink></item>
    <item>
      <title>Hosting a YouTrack instance on Windows Azure</title>
      <description>&lt;p&gt;&lt;em&gt;Note: this is a cross-post from the JetBrains &lt;/em&gt;&lt;a href="http://blog.jetbrains.com/youtrack/"&gt;&lt;em&gt;YouTrack blog&lt;/em&gt;&lt;/a&gt;&lt;em&gt;. Since it is centered around Windows Azure, I thought it is appropriate to post a copy on my own blog as well.&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href="http://www.jetbrains.com/youtrack"&gt;YouTrack&lt;/a&gt;, JetBrains&amp;rsquo; agile issue tracker, can be installed on different platforms. There is a stand-alone version which can be downloaded and installed on your own server. If you prefer a cloud-hosted solution there&amp;rsquo;s &lt;a href="http://www.jetbrains.com/youtrack/buy/index.jsp#incloud"&gt;YouTrack InCloud&lt;/a&gt; available for you. There is always a third way as well: why not host YouTrack stand-alone on a virtual machine hosted in Windows Azure?&lt;/p&gt;
&lt;p&gt;In this post we&amp;rsquo;ll walk you through getting a Windows Azure subscription, creating a virtual machine, installing YouTrack and configuring firewalls so we can use our cloud-hosted YouTrack instance from any browser on any location.&lt;/p&gt;
&lt;h2&gt;Getting a Windows Azure subscription&lt;/h2&gt;
&lt;p&gt;In order to be able to work with Windows Azure, we&amp;rsquo;ll need a subscription. Microsoft has several options there but as a first-time user, there is a 90-day free trial which comes with a limited amount of free resources, enough for hosting YouTrack. If you are an MSDN subscriber or BizSpark member, there are some &lt;a href="http://www.windowsazure.com/en-us/pricing/member-offers/"&gt;additional benefits that are worth exploring&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On &lt;a href="http://www.windowsazure.com"&gt;www.windowsazure.com&lt;/a&gt;, click the &lt;em&gt;Try it free&lt;/em&gt; button to start the subscription wizard. You will be asked for a Windows Live ID and for credit card details, depending on the country you live in. No worries: you will not be charged in this trial unless you explicitly remove the spending cap.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image002_3.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image002" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image002_thumb_2.jpg" border="0" alt="clip_image002" width="531" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The 90-day trial comes with 750 small compute hours monthly, which means we can host a single core machine with 1.5 GB of memory without being charged. There is 35 GB of storage included, enough to host the standard virtual machines available in the platform. Inbound traffic is free, 25 GB of outbound traffic is included as well. Seems reasonable to give YouTrack on Windows Azure a spin!&lt;/p&gt;
&lt;h2&gt;Enabling Windows Azure preview features&lt;/h2&gt;
&lt;p&gt;Before continuing, it is important to know that some features of the Windows Azure platform are still in preview, such as the &amp;ldquo;infrastructure-as-a-service&amp;rdquo; virtual machines (VM) we&amp;rsquo;re going to use in this blog post. After creating a Windows Azure account, make sure to enable these preview features from the &lt;a href="https://account.windowsazure.com/PreviewFeatures"&gt;administration page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image004_1.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image004" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image004_thumb_1.jpg" border="0" alt="clip_image004" width="532" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once that&amp;rsquo;s done, we can direct our browser to &lt;a href="http://manage.windowsazure.com"&gt;http://manage.windowsazure.com&lt;/a&gt; and start our YouTrack deployment.&lt;/p&gt;
&lt;h2&gt;Creating a virtual machine&lt;/h2&gt;
&lt;p&gt;The Windows Azure Management Portal gives us access to all services activated in our subscription. Under &lt;em&gt;Virtual Machines&lt;/em&gt; we can manage existing virtual machines or create our own.&lt;/p&gt;
&lt;p&gt;When clicking the &lt;em&gt;+ New&lt;/em&gt; button, we can create a new virtual machine, either by using the &lt;em&gt;Quick create&lt;/em&gt; option or by using the &lt;em&gt;From gallery&lt;/em&gt; option. We&amp;rsquo;ll choose the latter as it provides us with some preinstalled virtual machines running a variety of operating systems, both Windows and Linux.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image006_1.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image006" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image006_thumb_1.jpg" border="0" alt="clip_image006" width="532" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Depending on your preferences, feel free to go with one of the templates available. YouTrack is supported on both Windows and Linux. Let&amp;rsquo;s go with the latest version of Windows Server 2012 for this blog post.&lt;/p&gt;
&lt;p&gt;Following the wizard, we can name our virtual machine and provide the administrator password. The name we&amp;rsquo;re giving in this screen is the actual hostname, not the DNS name we will be using to access the machine remotely. Note the machine size can also be selected. If you are using the free trial, make sure to use the &lt;em&gt;Small&lt;/em&gt; machine size or charges will incur. There is also an &lt;em&gt;Extra Small&lt;/em&gt; instance but this has few resources available.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image008_1.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image008" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image008_thumb_1.jpg" border="0" alt="clip_image008" width="532" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the next step of the wizard, we have to provide the DNS name for our machine. Pick anything you would like to use, do note it will always end in &lt;em&gt;.cloudapp.net&lt;/em&gt;. No worries if you would like to link a custom domain name later since that is &lt;a href="http://www.windowsazure.com/en-us/develop/net/common-tasks/custom-dns/"&gt;supported as well&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We can also select the region where our virtual machine will be located. Microsoft has &lt;a href="http://matthew.sorvaag.net/2011/06/windows-azure-data-centre-locations/"&gt;8 Windows Azure datacenters globally&lt;/a&gt;: 4 in the US, 2 in Europe and 2 in Asia. Pick one that&amp;rsquo;s close to you since that will reduce network latency.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image010.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image010" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image010_thumb.jpg" border="0" alt="clip_image010" width="532" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The last step of the wizard provides us with the option of creating an availability set. Since we&amp;rsquo;ll be starting off with just one virtual machine this doesn&amp;rsquo;t really matter. However when hosting multiple virtual machines make sure to add them to the same availability set. Microsoft uses these to plan maintenance and make sure only part of your virtual machines is subject to maintenance at any given time.&lt;/p&gt;
&lt;p&gt;After clicking the &lt;em&gt;Complete &lt;/em&gt;button, we can relax a bit. Depending on the virtual machine size selected it may take up to 15 minutes before our machine is started. Status of the machine can be inspected through the management portal, as well as some performance indicators like CPU and memory usage.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image012.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image012" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image012_thumb.jpg" border="0" alt="clip_image012" width="531" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Every machine has only one open firewall port by default: remote desktop for Windows VM&amp;rsquo;s (on TCP port 3389) or SSH for Linux VM&amp;rsquo;s (on TCP port 22). Which is enough to start our YouTrack installation. Using the &lt;em&gt;Connect&lt;/em&gt; button or by opening a remote desktop or SSH session to the URL we created in the VM creation wizard, we can connect to our fresh machine as an administrator.&lt;/p&gt;
&lt;h2&gt;Installing YouTrack&lt;/h2&gt;
&lt;p&gt;After logging in to the virtual machine using remote desktop, we have a complete server available. There is a browser available on the Windows Server 2012 start screen which can be accessed by moving our mouse to the lower left-hand corner.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image014.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image014" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image014_thumb.jpg" border="0" alt="clip_image014" width="270" height="149" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;From our browser we can navigate to the JetBrains website and &lt;a href="http://www.jetbrains.com/youtrack/download/get_youtrack.html"&gt;download the YouTrack installer&lt;/a&gt;. Note that by default, Internet Explorer on Windows Server is being paranoid about any website and will display a security warning. Use the &lt;em&gt;Add&lt;/em&gt; button to allow it to access the JetBrains website. If you want to disable this entirely it&amp;rsquo;s also possible to &lt;a href="http://blogs.technet.com/b/thailand/archive/2012/09/13/how-to-disable-internet-explorer-enhanced-security-configuration-in-windows-server-2012.aspx"&gt;disable Internet Explorer Enhanced Security&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image016.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image016" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image016_thumb.jpg" border="0" alt="clip_image016" width="410" height="368" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We can now download the YouTrack installer directly from the JetBrains website. Internet Explorer will probably give us another security warning but we know the drill.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image018.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image018" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image018_thumb.jpg" border="0" alt="clip_image018" width="633" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you wish to save the installer to disk, you may notice that there is both a C:\ and D:\ drive available in a Windows Azure VM. It&amp;rsquo;s important to know that only the C:\ drive is persistent. The D:\ drive holds the Windows pagefile and can be used as temporary storage. It may get swiped during automated maintenance in the datacenter.&lt;/p&gt;
&lt;p&gt;We can install YouTrack like we would do it on any other server: complete the wizard and make sure YouTrack gets installed to the C:\ drive.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image020.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image020" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image020_thumb.jpg" border="0" alt="clip_image020" width="517" height="404" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The final step of the YouTrack installation wizard requires us to provide the port number on which YouTrack will be available. This can be any port number you want but since we&amp;rsquo;re only going to use this server to host YouTrack let&amp;rsquo;s go with the default HTTP port 80.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image022.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image022" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image022_thumb.jpg" border="0" alt="clip_image022" width="517" height="404" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once the wizard completes, a browser Window is opened and the initial YouTrack configuration page is loaded. Note that the first start may take a couple of minutes. An important setting to specify, next to the root password, is the system base URL. By default, this will read &lt;a href="http://localhost"&gt;&lt;em&gt;http://localhost&lt;/em&gt;&lt;/a&gt;. Since we want to be able to use this YouTrack instance through any browser and have correctly generated URLs in e-mail being sent out, we have to specify the full DNS name to our Windows Azure VM.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image024.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image024" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image024_thumb.jpg" border="0" alt="clip_image024" width="633" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once saved we can &lt;a href="http://www.jetbrains.com/youtrack/features/issue_tracking.html"&gt;start creating a project, add issues, configure the agile board, do time tracking and so on&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image026.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image026" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image026_thumb.jpg" border="0" alt="clip_image026" width="633" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see if we can make our YouTrack instance accessible from the outside world.&lt;/p&gt;
&lt;h2&gt;Configuring the firewall&lt;/h2&gt;
&lt;p&gt;By default, every VM can only be accessed remotely through either remote desktop or SSH. To open up access to HTTP port 80 on which YouTrack is running, we have to explicitly open some firewall ports.&lt;/p&gt;
&lt;p&gt;Before diving in, it&amp;rsquo;s important to know that every virtual machine on Windows Azure is sitting behind a load balancer in the datacenter&amp;rsquo;s network topology. This means we will have to configure the load balancer to send traffic on HTTP port 80 to our virtual machine. Next to that, our virtual machine may have a firewall enabled as well, depending on the selected operating system. Windows Server 2012 blocks all traffic on HTTP port 80 by default which means we have to configure both our machine and the load balancer.&lt;/p&gt;
&lt;h3&gt;Allowing HTTP traffic on the VM&lt;/h3&gt;
&lt;p&gt;If you are a command-line person, open up a command console in the remote desktop session and issue the following command:&lt;/p&gt;
&lt;p&gt;netsh advfirewall firewall add rule name="YouTrack" dir=in action=allow protocol=TCP localport=80&lt;/p&gt;
&lt;p&gt;If not, here&amp;rsquo;s a crash-course in configuring Windows Firewall. From the remote desktop session to our machine we can bring up Windows Firewall configuration by using the &lt;em&gt;Server Manager&lt;/em&gt; (starts with Windows) and clicking &lt;em&gt;Configure this local server&lt;/em&gt; and then &lt;em&gt;Windows Firewall&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image028.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image028" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image028_thumb.jpg" border="0" alt="clip_image028" width="644" height="385" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next, open &lt;em&gt;Advanced settings&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image030.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image030" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image030_thumb.jpg" border="0" alt="clip_image030" width="644" height="444" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Next, add a new inbound rule by right-clicking the &lt;em&gt;Inbound Rules&lt;/em&gt; node and using the &lt;em&gt;New Rule&amp;hellip;&lt;/em&gt; menu item. In the wizard that opens, add a &lt;em&gt;Port&lt;/em&gt; rule, specify TCP port 80, allow the connection and apply it to all firewall modes. Finally, we can give the rule a descriptive name like &amp;ldquo;Allow YouTrack&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image032.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image032" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image032_thumb.jpg" border="0" alt="clip_image032" width="447" height="337" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once that&amp;rsquo;s done, we can configure the Windows Azure load balancer.&lt;/p&gt;
&lt;h3&gt;Configuring the Windows Azure load balancer&lt;/h3&gt;
&lt;p&gt;From the &lt;a href="http://manage.windowsazure.com/"&gt;Windows Azure management portal&lt;/a&gt;, we can navigate to our newly created VM and open the &lt;em&gt;Endpoints&lt;/em&gt; tab. Next, click &lt;em&gt;Add Endpoint&lt;/em&gt; and open up public TCP port 80 and forward it to private port 80 (or another one if you&amp;rsquo;ve configured YouTrack differently).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image034.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image034" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image034_thumb.jpg" border="0" alt="clip_image034" width="532" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After clicking &lt;em&gt;Complete&lt;/em&gt;, the load balancer rules will be updated. This operation typically takes a couple of seconds. Progress will be reported on the &lt;em&gt;Endpoints&lt;/em&gt; tab.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image036.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image036" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image036_thumb.jpg" border="0" alt="clip_image036" width="609" height="223" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Once completed we can use any browser on any Internet-connected machine to use our YouTrack instance. Using the login created earlier, we can create projects and invite users to register with our cloud-hosted YouTrack instance.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.maartenballiauw.be/image.axd?picture=clip_image038.jpg"&gt;&lt;img style="background-image: none; float: none; padding-top: 0px; padding-left: 0px; margin-left: auto; display: block; padding-right: 0px; margin-right: auto; border: 0px;" title="clip_image038" src="http://blog.maartenballiauw.be/image.axd?picture=clip_image038_thumb.jpg" border="0" alt="clip_image038" width="609" height="307" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=QBZgjqvVQYc:wDuBo0YGp4Y:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=QBZgjqvVQYc:wDuBo0YGp4Y:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?i=QBZgjqvVQYc:wDuBo0YGp4Y:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=QBZgjqvVQYc:wDuBo0YGp4Y:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=QBZgjqvVQYc:wDuBo0YGp4Y:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=QBZgjqvVQYc:wDuBo0YGp4Y:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/maartenballiauw?a=QBZgjqvVQYc:wDuBo0YGp4Y:Jwdi1b3fU3Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/maartenballiauw?d=Jwdi1b3fU3Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/maartenballiauw/~4/QBZgjqvVQYc" height="1" width="1"/&gt;</description>
      <link>http://feedproxy.google.com/~r/maartenballiauw/~3/QBZgjqvVQYc/post.aspx</link>
      <comments>http://blog.maartenballiauw.be/post/2013/01/25/Hosting-a-YouTrack-instance-on-Windows-Azure.aspx#comment</comments>
      <guid isPermaLink="false">http://blog.maartenballiauw.be/post.aspx?id=e418798a-6b16-42de-8425-7d6f02abf8cf</guid>
      <pubDate>Fri, 25 Jan 2013 08:35:00 +0200</pubDate>
      <category>General</category>
      <category>ICT</category>
      <category>Software</category>
      <category>Windows Azure</category>
      <dc:publisher>maartenba</dc:publisher>
      <pingback:server>http://blog.maartenballiauw.be/pingback.axd</pingback:server>
      <pingback:target>http://blog.maartenballiauw.be/post.aspx?id=e418798a-6b16-42de-8425-7d6f02abf8cf</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://blog.maartenballiauw.be/trackback.axd?id=e418798a-6b16-42de-8425-7d6f02abf8cf</trackback:ping>
      <wfw:comment>http://blog.maartenballiauw.be/post/2013/01/25/Hosting-a-YouTrack-instance-on-Windows-Azure.aspx#comment</wfw:comment>
      <wfw:commentRss>http://blog.maartenballiauw.be/syndication.axd?post=e418798a-6b16-42de-8425-7d6f02abf8cf</wfw:commentRss>
    <feedburner:origLink>http://blog.maartenballiauw.be/post.aspx?id=e418798a-6b16-42de-8425-7d6f02abf8cf</feedburner:origLink></item>
  </channel>
</rss>
