How to use web.config transforms to replace appSettings and connectionStrings?

Category:
ASP.net
Publishdate:
01.01.2011
Hits:
102787

Introduction

This article will cover how you can use the new Visual Studio 2010 web.config transform concept to have a OneClick Deployment for your web applications. I will demonstrate how you can override sections of the web.config with the ones necessary for the release (e.g. appSettings and connectionStrings)

With Visual Studio 2010 Microsoft included specific web.config files for each solution configuration. Per default there are two settings: 'Debug' and 'Release'.


We will store the values for our local IDE inside the web.config and the specific settings in the individual configuration web.xxx.config file. As far as I know VS 2010 with Cassini and our local IIS 7.5 is only capable of reading the settings that are stored in the web.config. Selecting another configuration (like Release) will not force the web.config replacements to work on the localhost. It only has affect upon publishing the project.

How to create new solution configurations and the web.xxx.config files

You can easy add some more solution configurations (e.g. a configuration for your testserver) by clicking on the Configuration Manager
solution configuration

In the DropDownList for 'Active solution configuration' select '<New...>' and fill out a name for the new configuration.


Although the Checkbox for create new project configurations was checked, no new file named 'Web.Testserver.config' was created. But we can manually force it's creation. This context menu entry also become clickable for projects that have been converted into a VS 2010 project.
Rightclick on the Web.config and select 'Add Config Transforms'

Add Config Transforms
which results in:

How to replace the appSettings

1. Comments

The appSettings are an old way of storing settings in the web.config. Accessing them will not grant any type security.

At the moment (VS 2010 without any service pack)  I'm prefering appSettings over the designer generated applicationSettings (Project properties -> Settings) because using the web.config transform produces unwanted whitespaces or linebreaks for Strings that are stored as inner value of XML Tags. Strings that are stored as XML-Attributes are not affected.
This behaviour will affect in runtime errors. (Think of a setting that stores a directory name. If you use the transforms your setting will add a linebreak at the end of the foldername, which will ultimately result in a runtime error, because valid directory names do not contain line breaks)
Microsoft announced that VS 2010 SP1 will fix this problem. http://connect.microsoft.com/VisualStudio/feedback/details/544183/web-config-transform-writes-extra-line-break-spaces-to-values-elements-under-applicationsettings-section#

2. Walkthrough on how to replace the appSettings

Let's say you have some appSettings in your web.config:

<appSettings>
	<add key="GoogleAnalyticsEnabled" value="false"/>
	<add key="TestEnvironment" value="true"/>
</appSettings>

These are your local debug settings. Upon release you want the values reversed, meaning you want it to look like this:

<appSettings>
	<add key="GoogleAnalyticsEnabled" value="true"/>
	<add key="TestEnvironment" value="false"/>
</appSettings>

There are only a few thing you need to do. Open the Web.Release.config and insert the same appSettings block into it and add the attribute xdt:Transform="Replace" to the appSettings node. Afterwards your Web.Release.config will look similar to this (comments removed):

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
	<appSettings xdt:Transform="Replace">
		<add key="GoogleAnalyticsEnabled" value="true"/>
		<add key="TestEnvironment" value="false"/>
	</appSettings>
  <system.web>
    <compilation xdt:Transform="RemoveAttributes(debug)" />
  </system.web>
</configuration>

Thats everything you need to replace the appSettings upon publishing. Your publishing process will probably look familiar to this:

  1. Select your solution configuration you want to use. Because we want to test our Release settings, you need to select Release.
    Release
  2. Right-Click on your project and select Publish
  3. Select your publish method. I chose 'File System' but also works with other publish methods, like WebDav for instance.
  4. Press the "Publish" button

 

3. Fully functional sample:


Web.config

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="GoogleAnalyticsEnabled" value="false"/>
        <add key="TestEnvironment" value="true"/>
    </appSettings>
    <connectionStrings />
    <system.web>
        <compilation debug="false">
        </compilation>
        <authentication mode="Windows" />
    </system.web>
</configuration>

Web.Release.config

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <appSettings xdt:Transform="Replace">
        <add key="GoogleAnalyticsEnabled" value="true"/>
        <add key="TestEnvironment" value="false"/>
    </appSettings>
    <system.web>
        <compilation xdt:Transform="RemoveAttributes(debug)" />
    </system.web>
</configuration>

Published web.config

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="GoogleAnalyticsEnabled" value="true"/>
        <add key="TestEnvironment" value="false"/>
    </appSettings>
    <connectionStrings/>
    <system.web>
        <compilation>
        </compilation>
        <authentication mode="Windows" />
    </system.web>
</configuration>

How to replace connectionStrings

1. Walkthrough on how to change connectionStrings with web-transforms

Replacing connectionStrings is very similar to replacing appSettings.
Let's assume you have a single connectionString in your Web.config that holds credentials to your test database.

<connectionStrings>
	<add name="FooEntities" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string="Data Source=IP,PORT\Instancename;
		Initial Catalog=Foo;Persist Security Info=True;User ID=admin;Password=password;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient"/>
</connectionStrings>

Upon release you want to change the connectionString to the production server that it looks like the following.

<connectionStrings>
	<add name="FooEntities" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string="Data Source=LIVEIP,PORT\Instancename;
		Initial Catalog=Foo;Persist Security Info=True;User ID=admin;Password=password;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient"/>
</connectionStrings>

Copy your connectionString from the Web.config into your Web.Release.config and add the xdt:Transform="Replace" attribute:

<connectionStrings xdt:Transform="Replace">
	<add name="FooEntities" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string="Data Source=LIVEIP,PORT\Instancename;
	Initial Catalog=Foo;Persist Security Info=True;User ID=admin;Password=password;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient"/>
</connectionStrings>

Now you do have a working connectionString replacement for the solution configuration Release. For the publishing process view "How to replace the appSettings" from above.

2. Fully functional sample


Web.config

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="GoogleAnalyticsEnabled" value="false"/>
        <add key="TestEnvironment" value="true"/>
    </appSettings>
    <connectionStrings>
        <add name="FooEntities" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string="Data Source=IP,PORT\Instancename;
		Initial Catalog=Foo;Persist Security Info=True;User ID=admin;Password=password;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient"/>
    </connectionStrings>
    <system.web>
        <compilation debug="false">
        </compilation>
        <authentication mode="Windows" />
    </system.web>
</configuration>

Web.Release.config

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <appSettings xdt:Transform="Replace">
        <add key="GoogleAnalyticsEnabled" value="true"/>
        <add key="TestEnvironment" value="false"/>
    </appSettings>
    <connectionStrings xdt:Transform="Replace">
        <add name="FooEntities" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string="Data Source=LIVEIP,PORT\Instancename;
		Initial Catalog=Foo;Persist Security Info=True;User ID=admin;Password=password;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient"/>
    </connectionStrings>
    <system.web>
        <compilation xdt:Transform="RemoveAttributes(debug)" />
    </system.web>
</configuration>

Publish Web.config

<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="GoogleAnalyticsEnabled" value="true"/>
        <add key="TestEnvironment" value="false"/>
    </appSettings>
    <connectionStrings>
        <add name="FooEntities"
            connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string="Data Source=LIVEIP,PORT\Instancename;
			Initial Catalog=Foo;Persist Security Info=True;User ID=admin;Password=password;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient"/>
    </connectionStrings>
    <system.web>
        <compilation>
        </compilation>
        <authentication mode="Windows" />
    </system.web>
</configuration>

Comments:

Noel - 11.07.2014 - 02:58
It makes alot of sense...:) Thank you!

arvind Tiwari - 10.10.2013 - 14:33
I have understand about web config but regarding
web.debug.config why its slow please give best example.
another things which file generate when that mode published.

Tomot - 10.07.2013 - 14:59
@Eric: First of all, thanks for your comment. I've changed one occurance of "applicationSettings" to "appSettings" in the introduction.

Other than that, I can't find occurances where I'm using both word interchangeably. Would you mind pointing them out for me, so that I can correct them?

Eric - 10.07.2013 - 14:42
Just so you know, there can be an appSettings section, and and applicationSettings section in your web.config file. (You use them interchangeably in your description) Their structures are a bit different.

mberthely - 28.02.2013 - 05:24
this is pretty much strigth forward that other examples that I saw before. thanks

Michael M - 11.09.2012 - 17:37
Thank-you for this straight forward write-up. I am now using debug and release webconfigs and it is wonderful!

Johan - 26.06.2012 - 15:18
Nice work. We need more of this type of explanation and less rambling narcisists on youtube and product promos on microsoft.

Alex Z - 17.02.2012 - 16:47
Thank you for the great article, with clear directions and screenshots.
Why cant Microsoft do something like instead of their videos ? Who has time to sit and watch videos !

Dave - 17.07.2011 - 08:11
Made a typo on the connection string, compiled the deployment package, ran from command prompt, got an error from the dbFullSql portion of the msdeploy.exe.

Made a correction, and recompiled not only the service but republished and ran the deployment package, the new package still references the old string no matter what I do. I've cleaned, respecified a different initial database, etc. But no matter what it just keeps using the old string, any ideas. This is on the release version of the application.

Any help would be appreciated it.

Add a comment (due to recent massive spam, I've decided to only display new comments after a manual spam check):
Name
E-Mail (will not be displayed)  
Text