A problem when collaborating on web.config file

The same applies to an app.config file, of course.

When working with web.config file, a problem arises once multiple developers are working on the same application. The config file may contain machine or environment specific settings, which are different between developer machines and target (development/test/staging/production) environments.

Requirements

I do not want to think about what to do with my config settings during development, because of process obligations. When I add a setting I add it, and there it ends. Optionally, I also add the setting values for all possible target environments.

I do not want to notify other developers that I have added a setting. They need to receive it automatically

I do not want to store settings in multiple places (eg. seperate xml's). I want one config file.

I do not want to roll my own system, but make use of existing techniques of .NET and Visual Studio as much as possible.

Settings in deploys need to be handled without much hassle.

Options

On handling this problem, there are a few options.

Check-in the file

Check-in the file, overwrite each others settings, and try not to forget to not check in yourself.

Well, this is not really a solution. I've been here, this is exactly the problem that needs to be fixed, this causes lots of friction during development.

Don't check-in the file

Can't check-in the file? Let's have some self-control and don't check in our config changes. We know how long that's going to last. One moment of carelessness and the system is lost.

Ignore the file

We can tell our source control system to ignore the files. This way we don't have to be disciplined. Everyone can use their own setting values.

This solves the problem of not overriding each others settings, but introduces new problems.

How will other team members receive the setting?

How will you deploy your new settings to the target environments?

You could add an extra "central" configuration file, which can be used for deploys and consulted by other team members. But that causes the settings to be in 2 places which then needs to be maintained again.

The most elegant solution so far

Following is an approach that seems to be fixing all of these problems:

We have one single, checked-in and complete web.config file, developer setting overrides and target environment overrides for deploys. And we are only using built-in techniques.

Developer setting values for appSettings

The appSettings section provides an option to override settings in a separate file. Settings can be added to the central file and overridden in a separate file. Developer specific values can then be added to the separate file.

The files can be arranged, so that there are template files for the developer files in a separate (solution) folder.

When a developer starts working on the project, he can copy the files from there into the Web project. The files are known in the project, so they will be indicated as "missing", until you copy-paste or create them.

These template files are checked in, obviously. The local version is not checked in.

These files do cause second versions of config files, which could be seen as friction. But since these files will remain empty, they need no management or maintenance at all.

How are deploys handled?

For deploys, we use Web Deploy and of course, for deploys we make use of the config transforms. The developer specific settings can be removed and the target environment settings can be put in place:

Below is an example of a config transform, which does the necessary actions to create a correct web.config for target environments:

Some words of explanation:

RemoveAttributes(file): this transform is used to remove the file attribute from the appSettings section

xdt:Transform="Replace" on connectionStrings: this will replace the whole connectionStrings section.

ASP.NET MVC has a somewhat hidden, but pretty well known setting to build views when building an MVC project.

This setting can be enabled and disabled in the csproj file, by opening it up in a text editor.

The setting is called

<MvcBuildViews>false</MvcBuildViews>

By enabling the setting (replace false with true, duh :-), aspnet_compiler will be run to compile the views. Enabling this setting is very useful, because otherwise code errors in the view do not get noticed until runtime, and might not be noticed in time.

However, there's downside: enabling this setting slows down your builds quite a bit.

There's a way to realize fast(er) builds on the developer machines, by letting the view compilation only happen on the CI builds.

If your developer builds are built using the Debug configuration, and CI builds happen using the Release configuration, you can change the .csproj file as follows:

I used to blog about AutoCAD and .NET over at http://cupocadnet.blogspot.com/ . I'm not really working on that type of projects anymore, and decided to start this blog for more ASP.NET (MVC) and web development stories.