Handling Web.Config Variants in Source Control-based Solutions

If several developers work on the same projects or solutions, sooner or later you need to manage the .config files of these developers (e.g. for local databases vs. team database, local log files and directories, and so on).

Of course, if you use a source control system, such as TFS or SVN, you don’t want the personal settings of one developer to overwrite the settings of another one.

Separate SCS config files

Usually my approach is to not check in the app.config or web.config files, but instead create copies of these files as config templates (e.g. web.tfs.config, app.svn.config) and have these copies under source control.

Recently I saw a big obstacle to this approach, and it is called TFS Team Build, an implementation of Continuous Integration.

I definitely wanted to avoid having to check out the config files, rename them so as to match the CI backend, build, and then revoke the check out.

User-specific config files

Next try, have app.config and web.config in separate sub-directories of each project, and simply copy the developer-specific app.config to app root before compilation.

While this works for app.config, it does not work for web.config in cases that the web.config contains an <authentication> element. Then the error is raised

Error 3 It is an error to use a section registered as allowDefinition=’MachineToApplication’ beyond application level. This error can be caused by a virtual directory not being configured as an application in IIS.

(Yes, I encountered this error message before, and in that case you should be able to solve the problem by running Clean on the project or the solution)

Include user-specific config files using configSource

Next try, move all developer-specific (or installation-specific) config sections to separate .config files and include these .config section files using configSource.

When you’re done, your web.config will look something like this:

  <log4net configSource="Config\log4net.config" />
  <appSettings configSource="Config\appSettings.config" />
  <connectionStrings configSource="Config\connectionStrings.config" />
    <client configSource="Config\system.serviceModel.client.config" />

Copy the original contents of the web.config to the new files in the Config directory, e.g.:

<?xml version="1.0"?>
    <add name="default" 
        connectionString="Data Source=localhost;Initial Catalog=cat;Persist Security Info=True;User ID=userid;Password=pwd" 
        providerName="System.Data.SqlClient" />

The Config directories then further contains one directory for each developer or installation environment.

To activate one of these configurations, simply copy the config files of one directory into the Config directory, but do not check-in the changes in the Config directory itself.

You can also write a batch file to perform the copy statements and invoke the .cmd from Solution Explorer.

The only drawback I see with this solution is that you lose Intellisense with these partial config section files.


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

%d bloggers like this: