Oct 172011

Web.config Transformations

A great feature in Web Deploy (Microsoft’s latest website publishing technology) is the ability to transform your default web.config to a customised version, driven by the configuration being built. So you can have different configurations for Test, Staging and Production etc. with transformation rules that change only the settings that differ in each of those environments.

To add web.config transformations in Visual Studio, simply right-click your web.config and select Add Config Transforms. If the option is disabled, you probably need to add a new configuration to the solution using the Configuration Manager. The transformation language is XML Document Transform (XDT) which has been covered very well by Scott Hanselman and the syntax is fully documented.

You may be surprised to learn that TFS build does not automatically apply your web.config transformations when it generates the _PublishedWebsites folder containing your compiled web application. This is an inconvenience if you aren’t using the Web Deployment Tool to deploy the application, and just want a package of files customised to the right environment. The fix for this is fairly straightforward: to get TFS build to run the transformations you need to pass some additional arguments to MSBuild telling it to use the new Web Publishing Pipeline. This can be done using the build definition’s MSBuild Arguments parameter (if you are using the default build template or a custom template derived from it). Simply add /p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false as shown below.

* * * * *

App.config Transformations

Web.config transformations are great, but you can also transform app.config files. You need to make some changes to the MSBuild project file to associate the configs and import a transformation MSBuild script, but that’s all. Here’s how to do it using the neat solution by Sayed Ibrahim Hashimi:

First, if your project doesn’t have an app.config file, add one using the provided template (under the General category when you choose to add a new item to a project). Next, add further app.*.config files using the same template – one for each configuration in the project except Debug.

Add transforms to the configuration-specific files. For testing, you could use something simple like:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<add key="MyNewKey" value="MyNewValue" xdt:Transform="Insert"/>

Next, associate the config files by editing the project file (.csproj or .vbproj) either in a text editor or in Visual Studio (but you will need to unload the project first). Locate each app.*.config reference like…

<None Include="app.Release.config" />

…and change it to…

<None Include="app.Release.config">

Next, add the following just above the final Project closing tag:

<Import Project="AppConfig.Transformation.targets" />

Finally, download the script from Sayed Ibrahim Hashimi’s blog and save it as AppConfig.Transformation.targets to the same location as your project file. Build the project and you should see the transformed app.config in the output folder.

We use this file in several projects so deploy it to C:\Program Files\MSBuild on each development and build machine and reference that folder using $(MSBuildExtensionsPath32), instead of adding it to every project.

  9 Responses to “Web and App Config Transformations with TFS Build”

  1. /p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false didn’t work for me.
    Without these arguments I get web.config and web.Release.config as expected. With these arguments I just get web.config but my transforms are not applied. Any ideas?

  2. Couple of ideas… Does the transform take effect properly when you build in Visual Studio? Have you chosen the configuration you want to use in the build definition?

  3. Thanks for this post. Ww have been working all day to get TFS use transformations and its now solved. A lot of other blogposts uses _WppCopyWebApplication… and it does not work, may be some old TFS stuff?

  4. Thank you so much for this tip.
    It just worked like charm!

    I am lucky to find your post thru StackOverflow without much roaming around.

  5. What if you have chosen not to use “OutDir” or [OutputDirectory]=BinariesDirectory? Meaning ,if you want to keep the buod output “AS IS” i.e. as configured in your project to “bin\$(Configuration)” – In this case, when TeamBuild executes there will be neither “Binaries” nor “_PublishedWebsites” folder – I was hoping it would still apply the transforms and place it in “obj” folder – but no luck! – Any ideas?

    Thanks for this post btw

  6. I am using 2013 Update 2. This does not seem to work. Can you look at my settings? /p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false /p:DeployOnBuild=true /p:PublishProfile=”DEV – JAM UNC DEPLOYMENT”

    I ended up manually adding the new configuration to the build definition. That gave me the correct result.
    Here is an example.

  7. /p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false didn’t work for me.
    Without these arguments I get web.config , web.Release.config and web.Debug.config as expected. With these arguments I just get web.config but my transforms are not applied. Any ideas?

  8. Thank you, this appears to have resolved my problem. This is really strange, the builds were working perfectly up until yesterday (for the last 2 or 3 years)! And they now randomly require the /p:UseWPP_CopyWebApplication=true /p:PipelineDependsOnBuild=false parameters to work… Weird!

    We are on TFS and Visual Studio 2013 Update 4. I’m wondering if there was a pending reboot on the build servers that hadn’t picked it up that change yet?

Sorry, the comment form is closed at this time.