[Dev Tip] How to use web.config transforms to replace appSettings and connectionStrings?


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:

1
2
3
4
<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:

1
2
3
4
<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 yourWeb.Release.config will look similar to this (comments removed):

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0"?>
    <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

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0"?>
    <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

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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.

1
2
3
4
<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.

1
2
3
4
<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 thexdt:Transform=”Replace” attribute:

1
2
3
4
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0"?>
    <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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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>
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s