working - web.config transform replace section




How do you deal with connection strings when deploying an ASP.NET site? (6)

Here's another thing you can try:

Using SQL Server Configuration Manager, make a db Alias for your development database so that the web.config file can be the same on both your development box and the production server.

Right now our test and production databases are on the same server, but with different names. Deploying has meant editing Web.config to change all the connection strings for the correct database. A step which I forget all too frequently...

We've finally created a new database server for testing, and I'm moving the databases over... but now the server will be different and we'll still need to deal with connection string issues.

I was thinking of managing it via a hosts file, but the thought of switching that on my desktop machine whenever I need to test against production data seems cumbersome at best.

So I'm just wondering if there's a better way out there. Something that would build with a "production" web config for deployment would be ideal...


I usually have three separate web configs: one for my development machine, one for QA, and one for production. The development one connects to my local SQL database (which is firewalled from outside) and it is the default web.config. The others are named web-prod.config and web-qa.config. After publishing I delete the two that I don't need and rename the correct one to web.config. If I forget, the app breaks the first time it attempts to access the database, since the default config references one it can't get to.

Since IIS refuses to serve up a file named .config, I make sure they all end in .config instead of say web.config-prod or web.config-qa.


There is a related question here:

Improving Your Build Process

Config files come with a way to override the settings:

<appSettings file="Local.config">

Instead of checking in two files (or more), you only check in the default config file, and then on each target machine, you put a Local.config, with just the appSettings section that has the overrides for that particular machine.

If you are using config sections, the equivalent is:

configSource="Local.config"

Of course, it's a good idea to make backup copies of all the Local.config files from other machines and check them in somewhere, but not as a part of the actual solutions. Each developer puts an "ignore" on the Local.config file so it doesn't get checked in, which would overwrite everyone else's file.

(You don't actually have to call it "Local.config", that's just what I use)


This might help to some people dealing with Settings.settings and App.config: Watch out for GenerateDefaultValueInCode attribute in the Properties pane while editing any of the values in the Settings.settings grid in Visual Studio (Visual Studio 2008 in my case).

If you set GenerateDefaultValueInCode to True (True is the default here!), the default value is compiled into the EXE (or DLL), you can find it embeded in the file when you open it in a plain text editor.

I was working on a console application and if I had defaults in the EXE, the application always ignored the configuration file place in the same directory! Quite a nightmare and no information about this on the whole Internet.


You could create a custom object, override the ToString method, and pass myObject.ToString() in as the parameter for those objects, eg.

class CustomObject
{
    override public string ToString()
    {
         // In here would go whatever logic you use to decide 
         // which conn string should be returned
         return "Data Source=server; User ID=user; Password=password;" + 
                   "Initial Catalog=" + Session["DBName"];
    }
}

Then to use it:

CustomObject co = new CustomObject();
SqlConnection conn = new SqlConnection(co.ToString());

.NET Configuration (app.config/web.config/settings.settings)

Any configuration that might differ across environments should stored at the machine level, not the application level. (More info on configuration levels.)

These are the kinds of configuration elements that I typically store at the machine level:

When each environment (developer, integration, test, stage, live) has its own unique settings in the c:\Windows\Microsoft.NET\Framework64\v2.0.50727\CONFIG directory, then you can promote your application code between environments without any post-build modifications.

And obviously, the contents of the machine-level CONFIG directory get version-controlled in a different repository or a different folder structure from your app. You can make your .config files more source-control friendly through intelligent use of configSource.

I've been doing this for 7 years, on over 200 ASP.NET applications at 25+ different companies. (Not trying to brag, just want to let you know that I've never seen a situation where this approach doesn't work.)