Among the many nice features introduced in Visual Studio 2010 were web config transforms.
These allow you to specify an XML transformation file corresponding to each of your build configurations (Debug, Release or whatever you like) specifying additions, deletions and alterations to produce the final Web.config for the build configuration in question. It goes without saying that including these transforms in your automated build process would neatly take care of an ever-present and difficult problem (although not as bad as male pattern baldness or the question of why those little Father Christmas figures you buy to hang on Christmas trees always insist on facing the wrong way).
If you are using deployment packages (as we are strongly encouraged to do) the process is relatively straightforward, since the transforms are designed to be applied when the application is published, and there is documentation on MSDN describing this scenario.
On the other hand, some of us are still stuck with XCopy deployment: this is especially common where you have limited control over the server or servers where the application will be deployed.
Finding myself in this situation I found that there was very little (as in pretty much nothing) said about applying transforms in this situation, to the extent that I started to wonder if I was weird for wanting to do it.
Eventually I concluded that I wasn’t any more weird than I had been when I started, so through poring over samples designed for the scenarios that people do talk about, and trial and error followed by more error and then additional trial I eventually came up with an approach that works and doesn’t take much effort (when I first got it working my approach was clunkier and included unnecessary steps and so on, but as I learned more I was able to simplify it down to something I consider acceptable).
So, my preferred approach involves an addition to your web application’s project file (which is as you hopefully know also an MSBuild definition file) and the addition of a single parameter to the build definition.
First, right-click your project file in the Solution Explorer and select “Unload Project”, then right-click the unloaded project file and select the Edit option.
Before the final end tag (“</Project>”) add the following:
<Target Name="AfterBuild" Condition="$(IsAutoBuild)=='True'">
<DeleteAfterBuild Include="$(WebProjectOutputDir)\Web.*.config" />
<TransformXml Source="Web.config" Transform="$(ProjectConfigTransformFileName)" Destination="$(WebProjectOutputDir)\Web.config"/>
<Delete Files="@(DeleteAfterBuild)" />
“IsAutoBuild” is an arbitrarily named parameter (you can replace it with anything you like) passed from the build definition.
Assuming you have saved and checked on your project file and are in the process of creating a build definition, on the Process step of your build definition you will find under the Advanced heading a field labelled “MSBuild Arguments”. Enter the value /p:IsAutoBuild=”True” (or whatever else you may have named your parameter).
This causes the condition we’re testing to evaluate to true when the build definition executes, so when the build completes transform is applied and the output Web.config file updated accordingly, after which the Web.Debug.config and Web.Release.config files (and any for other build configurations you may have) are deleted from the output directory (since they aren’t very useful when you come to actually deploy the application).
The end result is that when you open the output from your build, the _PublishedWebsites folder will contain a fully deployable version of your web application with the Web.config file transformed according to the rules you’ve defined in Web.Debug.config, Web.Release.config etc.
Which is pretty nifty.