When tasked with configuration management responsibilities, you normally have several environments to which you must deploy your systems and most often, your web.config files have different information for each environment. Several approaches have been used to address the problem this situation creates such as using T4 (Text Template Transformation Toolkit) or simply creating a separate configuration file for each environment. I’ve personally used the latter most often as it is a quick and simple solution to the problem and works well for Click Once deployments too. The challenge with this, however (especially in a team environment), is keeping the config files in sync when you add or change something- most developers forget to update the rest of the files and then deployments become a nightmare.
Enter the wonderful world of Web.config transforms. In the spirit of keeping this short, I’m not going to cover everything about how the transforms work. There is great reference documentation from Microsoft here: http://msdn.microsoft.com/en-us/library/dd465326(VS.100).aspx
We have to start with a quick overview of Web Projects. When building web applications with Visual Studio, there are two types of projects one may chose: Web Application or Web Site. A discussion on which type of project is “better” is a matter for another day. A great article exploring this question may be found here: http://vishaljoshi.blogspot.com/2009/08/web-application-project-vs-web-site.html
A quick summary of the some important points, however, is this. Web Sites do not require precompilation and may therefore be updated “on the fly” allowing for quick hot-fixes in production environments. It is, of course, debatable as to whether or not that is a good thing. The downside is they don’t take advantage of Web.config transformations and all of the other great tools Microsoft is making available like the Web Platform Installer. Web Applications, on the other hand, do take advantage of many of these great tools. The downside is that you must recompile the code if you make any changes making debugging a bit more cumbersome and and quick fixes require full blown deployments. Again, there are many merits and many flaws to both choices, but I want to review the wonderful new world of Web.config Transforms found in Web Application Projects.
Publish Profile & Configurations
Web Application Projects have a new Profile feature in the Publish functionality. Right click on the project and chose Publish, like so:
There are two important aspects to this example: 1) Profile Name and 2) Build Configuration. I’m not going to talk about all of the Publish Methods available because this too is a topic for another post. For now, my publish method of choice is “File System”.
Simply create a profile for each of your environments. Visual Studio stores these in a publish.xml file and are kept locally. You can add these to source control of course if you want to make them available to your team. The way I use the File System methodology is this: “Dev” Profile = UNC path of the website on the dev server, “Test” Profile = UNC path of the website on the test sever, etc.
Let’s assume for this example you have 4 environments: 1) Local Dev, 2) Development, 3) Testing, and 4) Production. Use the Configuration Manager to create a Configuration for each of your environments. “Debug” works for Local Dev and “Release” works for Production, so let’s create two new configurations for Dev and Test. Note that my “Dev” environment is a development server, not my local machine.
Now that that we have Configuration for each of the environments, it’s time to add the transform files to the web.config. Right click on your Web.config file and you’ll see a spiffy option called “Add Config Transoms”. Click this and poof, Visual Studio will add transforms for each of your new Configurations.
Refer to the MSDN article for full details of the transform language, but it’s quite simple to replace data. The easiest things to do are matching a specific key (such as a connection string) or replacing an entire element. The greatest thing about Web.config transforms is that you only need to keep the deltas in the transform files, but using replace works well if you don’t want to learn the fine points of the transformation language (I use this for my Enterprise Library configuration blocks).
Replacing a Connection String
Replacing a connection string is done like this (forgoing the obvious discussion of how connection strings should always be encrypted):
<add name="Axapta.Data.Properties.Settings.AxaptaConnectionString" connectionString="Data Source=XX;Initial Catalog=ax50_test;uid=XXX;pwd=YYY!@#QWE" providerName="System.Data.SqlClient" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
Replacing an entire Element
<loggingConfiguration name="Logging Application Block" tracingEnabled="true" defaultCategory="" logWarningsWhenNoCategoriesMatch="true" xdt:Transform="Replace"> ... </loggingConfiguration>
Once you get everything setup, you’re basically done. Now when you use the Publish functionality, Visual Studio will apply the transforms to your deployed Web.config based on your active configuration. Thus, deploying becomes a three step process: 1) Select your configuration in the Configuration Manager, 2) Select your Profile in the Publish Tool, and 3) Click Publish!
One might be able to write a small book on the topics covered in this article, but hopefully I kept it short and sweet so you can use it to get jump started or as a quick reference.
Hope this helps someone.
Elegant Software Solutions