Thursday, March 6, 2014

Web Configuration Transformation and Web Project Deployment

I thought to share something I first learned back in 2011 when I prepared for Microsoft certification examination for ASP.Net 4.0.  latterly I put it in use in my project. Since I put it in use, I start to appreciate it more. I could not think otherwise how could I do it without significant development effort. (of course, nobody wants to write code if we do not have to!). It has some relevancy to what we do in our project and if you are using VS2010 or above or thinking of using VS2010 or above for your Web app, whether it is classical ASP.Net form or MVC, you will find it interesting. Especially those who are involved in build/ deployment or tokenization process might find it useful or at least you will have an alternative to what you are using now in designing deployment strategy Visual Studio 2010.



ok, let me get it started…



Before Visual Studio 2010, ( like Visual Studio 2008 we are using), when you create an ASP.Net Web Project, IDE will add a Web.Config file to your project. if you want to have different setting in different regions ( Test, Staging or Production), you need to replace the region specific setting in the web.config file yourself. Some do it manually, some create some kind tokenization process to handle it. In order to deploy the project to a server you need to add a Web setup project in your solution and configure it to make a MSI file then copy the MSI file to the server you want to install and install the MSI package there.



This scenario is not ideal by all measures. If you are doing it manually, you tend to make mistakes as humans always do, if you are doing it using a tokenization tool, you will have one more step to worry about… as for MSI file installation, there are many shortcoming associate with it  If you want to use the built-in publishing process, you will find difficult to do the tokenization process.



well, starting with Visual Studio 2010, Microsoft introduced a process call “Configuration Transformation”.



After a Web project is created, you will see not only Web.config file, but also 2 files under it. please refer to the screen shot below:


 The 2 new files you did not see in Visual Studio 2008 are Web.Debug.config and Web.Release.config file.  “Debug” and “Release” is directly link to the default “Build Configurations” IDE created for you, Debug mode and Release mode. If you want to created more Build configuration using “Configuration Manager”, you will be able to add new “Config Transformation” for the new build configuration you created.  As you can see in the following screen shot, after I created a new Build Configuration, “Staging” I can add Config Transformations, and after I do  that I got one more file created



Let’s say in your project you have a DB connection and a setting, which will be different in different region.. you will most likely have your web.config file like the following:

<connectionStrings>

    <add name="ApplicationServices"

         connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"

         providerName="System.Data.SqlClient" />

  </connectionStrings>

  <appSettings>

    <add key="BaseAddress" value="http://localhost:3593/"/>

  </appSettings>



then you will have the same setting but different values in these Config Transformations.



Release:

<connectionStrings>
    <add name="ApplicationServices"
         connectionString="Data Source=ProdServer;Initial Catalog=ProdDB ;Integrated Security=SSPI;"
         providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="BaseAddressvalue="http://ProdServerAddress/"/>
  </appSettings>


Debug:

<connectionStrings>
    <add name="ApplicationServices"
         connectionString="TestServer;Initial Catalog=TestDB ;Integrated Security=SSPI;"
         providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="BaseAddressvalue="http://TestServerAddress/"/>
  </appSettings>


Staging:

<connectionStrings>
    <add name="ApplicationServices"
         connectionString="StagingServer;Initial Catalog=StagingDB ;Integrated Security=SSPI;"
         providerName="System.Data.SqlClient" />
  </connectionStrings>
  <appSettings>
    <add key="BaseAddressvalue="http://StagingServerAddress/"/>
  </appSettings>


But if we stop like that it won’t work. This is the time to introduce transformation process.  just pick up any of these transformations as an example: ( let’s say I pick Release), I need to add some transformation code in the transformation file:


Release:

  <connectionStrings>
    <add name="ApplicationServices"
         connectionString="Data Source=ProdServer;Initial Catalog=ProdDB ;Integrated Security=SSPI;"
         providerName="System.Data.SqlClient"  xdt:Transform="SetAttributes" xdt:Locator="Match(name)/>
  </connectionStrings>
  <appSettings>
    <add key="BaseAddressvalue="http://ProdServerAddress/" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"/>
  </appSettings>


What does it mean here? for the first one, it means go to the Config file and look for any connection string setting with the name of ApplicationServices and replace all its attributes with the ones here when the build mode is Release build. The second line means look for a setting with the key of   BaseAddress and replace all its attributes with the ones here. ( of course, you would not want to hard code id and password here, instead you want to use integrated security for database security, but you get the idea here, right?)

Okay, with all these set up, your build and deployment is just a few button clicks.

You can choose “Web Deploy” File System Deploy” or “FTP Deploy”. For my case, I use “File System Deploy” for on-promise server deployment, and I use “Web Deploy” for Azure web site deployment.  For Azure Web site deploy, all you need to do is load the Publish Profile you downloaded from Azure portal and you are all set. For different region, you just choose different Build Configuration.  



When you are doing Web publishing, the IDE is smart enough to detect the versions of the affected components and only push the components that have been changed. The preview function allow you to see what will be deployed to the site.  This greatly reduced the time spent and the risk associated with deployment process. The following is the screenshot of the preview screen.



once you are happy with the preview you see, all you need to do is click on <Publish> button. the IDE will make appropriate build based on your selection, transform the web.config file with the transformation you have and published the bits to the site. at the end of it, it will launch IE with your site opened in it. For my site, with the size of 50MB, the publishing process takes 1 to 2 minutes if it is fresh build. If it is a update build, it just takes sub-seconds. Of cause, the IDE needs to build the solution first. In my experience, I find it is better to do a “Rebuild All” before publishing would save you some time, in case the build produce problems.  



This could potentially replace the tokenization process we use if we decided to upgrade to VS 2010 or above.  Please refer to the links below for further reading on Web Configuration Transformation



http://msdn.microsoft.com/en-us/library/dd465326(v=vs.110).aspx

http://msdn.microsoft.com/en-us/library/dd465318(v=vs.100).aspx

If you are on “Standard” tier in Azure, you are offered backup restore functionality for your web site. with that I can backup your site  before deployment, and in case deployment encountered problem, you can  easily rollback to the one you had before your deployment process. From the screenshot below you can see a link with the caption of <BackUPS>



As always, feedbacks and comments on this article and suggestions on future writing are welcome.


No comments:

Post a Comment