Moving the Web.Config to Production in ASP.NET 4.0
Microsoft has another solution for managing your Web.config file as you move your site to production. And, no matter what the name of this feature suggests, you don't have to learn XSLT to use it.
The Web.config provides a central point of control for those few, but critical, items that change between the development/test environment and the production environment. Of course, it also means that if you deploy your Web.config file incorrectly, your production system ends up updating your development database and running in debug mode.
In many ways, the best solution to managing the Web.config file is the simplest: set up your Web.config on your production server and never change it again. Microsoft provided a more sophisticated solution with Web Deployment Projects (covered here), which allow you to replace sections of the config file as part of your deployment process.
With ASP.NET 4.0, Microsoft has another solution: Web.config transformation. Don't Panic! When I hear the word "Transformation" I immediately think of XSLT and, while I'm comfortable with XSLT, most reasonable developers shy away from trying to develop XSLT-based solutions. While there may be XSLT processing going on under the hood you don't have to deal with it yourself. Or, at least, not much.
There is really only two pieces of bad news here. The first is that the technology only works with ASP.NET Web Applications (i.e. the sites you create with File | New Project, not the ones you create with File | New Web Site). The second piece is that using this feature also requires you to commit to using the new Web Deployment Tool zip file format which only works with IIS 7.
It's easy to spot the new technology in Solution Explorer: Your Web.config file has a plus sign beside that, when you click it, reveals two more files nested underneath: Web.Debug.config and Web.Release.config. As you might assume, you put the elements that are common to your development and production environments in your Web.config file. In the Web.Release.config file you put the elements specific to your production along with the commands specifying how the changes are to be applied. You can add additional config files (e.g. Web.QATesting.config).
Which config file's changes are applied is driven by the current setting in Build | Configuration. If the current setting is set to "Release" then the publish process takes the contents of the Web.Release.config file and applies it to the Web.config file to create the file that will be included in the Web Deployment package.
To specify the changes to be made, you must first add the namespace for the transformation commands to your Web.Release.config file, like this:
You then add the element that you want to replace, remove or modify to the Web.Release.config file along with the appropriate transformation command added as an attribute to the element. For instance, to replace the entire connectionStrings element in the Web.config file, you add to the Web.Release.config file a connectionStrings element with a Transform attribute specifying that the Release element is to replace the existing element. That's what this example does, for instance:
... production connection strings...
Setting Transform to Insert allows you to add a new element within the current parent element. The Remove and RemoveAll settings allow you to remove items you don't want. Rather than replace the whole connectionStrings element, this example would remove all the existing connection strings and adds a new one:
<add name="NewConnectionString" xdt:Transform="Insert"
RemoveAttributes allows you to remove selected attributes (with their values) providing a clean way to ensure that you get rid of that pesky debug setting:
<compilation xdt:Transform="RemoveAttributes(debug)" />
As that example shows, you can pass parameters to the Transform command that you're invoking (in this case, a list of attributes you want removed). This is where a little knowledge of XPath comes in handy since you can pass an XPath location to the commands to specify an element. For instance, you can use InsertBefore and InsertAfter to specify where new elements are to be added by passing an XPath statement that specifies the element that your new element is to be inserted before (or after). This example inserts a machineKey element before the existing membership element:
If you've been bitten by problems in moving your Web.config file to production, this feature might be a reason to move to IIS 7, Visual Studio 2010, and .NET 4 all by itself.
Peter Vogel is a principal in PH&V Information Services, specializing in Web development with expertise in SOA, client-side development, and user interface design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His most recent book ("rtfm*") is on writing effective user manuals, and his blog on language and technical writing can be found at rtfmphvis.blogspot.com.