First of all, since a VS project comes with just 2 build configurations (Debug and Release), we need to create a new build configuration for Staging. In this way we’ll be able to have a Web.config transformation for it as well.
We can add the new build configuration from the Configuration Manager:
Now that we have all the build configurations we need we can create a config transformation for our new Staging build configuration (we should already have the one for Debug and Release) by right-clicking on our Web.config and selecting “Add Config Transform”. A new Web.Staging.config file will be added under the Web.config in the solution.
Working with Config Transformation files
We can use the config transformation files to specify transformations to apply to the original Web.config in order to obtain any configuration-related Web.config. Since the original Web.config is often related to a Development environment we normally don’t have any transformation to apply for the Debug build configuration (we just use the original Web.config). So what we basically do is to define transformations for the Staging and Release build configurations by replacing any configuration key that need to be different between the environments.
Updating a Connection String
A thing that is often useful to change between different environments is the value of connection strings, to be able to connect to a different DB based on the environment we are publishing to. Here is an example configuration in our original Web.config:
<connectionStrings> <add name="ConString" connectionString="myDebugCS" /> </connectionStrings>
And here is what we need to write in our Web.Staging.config transformation file to change its value for our Staging environment:
<connectionStrings> <add name="ConString" connectionString="MyConStr" xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/> </connectionStrings>
What we are doing with the new “xdt” attributes is to tell that we want new attributes values for the item who match the “name” attribute.
As result when we’ll publish under Staging build configuration our “connectionString” property for the “ConString” connection string will be replaced with the “MyStagingCS” value.
Updating an AppSetting configuration
<add key="MyConfigurationKey" value="MyConfigurationValue" xdt:Transform="SetAttributes" xdt:Locator="Match(key)"></add>
Adding an AppSetting configuration
<add key="MyConfigurationKey" value="MyConfigurationValue" xdt:Transform="Insert"></add>
Removing an AppSetting configuration
<add key="MyConfigurationKey" xdt:Transform="Remove" xdt:Locator="Match(key)"></add>
Replacing a node with all its subnodes
In this case we want to replace the whole node and its content (so the inner “network” node as well) for the smtp configuration whose “from” attribute is “email@example.com”.
<smtp deliveryMethod="Network" from="firstname.lastname@example.org" xdt:Transform="Replace" xdt:Locator="Match(from)"> <network host="my-company.host.com" port="25"></network> </smtp>
Replacing a node based on its subnodes
This is something that can happen if we have to replace something about assembly bindings, which is defined by a list of nodes like this:
<dependentAssembly> <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /> <bindingRedirect oldVersion="22.214.171.124-126.96.36.199" newVersion="188.8.131.52" /> </dependentAssembly>
Let’s imagine that we want to replace the “dependantAssembly” configuration node for the “System.Web.Helpers” assembly. Unfortunately
this information is written inside the “assemblyIdentity” inner node, so we have to specify a more complex rule:
<dependentAssembly xdt:Transform="Replace" xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Web.Helpers')"> <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"></assemblyIdentity> <bindingRedirect newVersion="184.108.40.206" oldVersion="0.0.0.0-220.127.116.11"></bindingRedirect> </dependentAssembly>