views:

1843

answers:

4

Can anyone suggest a good way to manage multiple web.config files?

For example, I have a development web.config I use on my localmachine named "localWeb.config" and then one I use for production called "prodWeb.config". I keep the .config extensions so no one can access them from the web server.

localWeb.config will for example have a connection string to a development database while prodWeb.config has one to the production database.

Currently, I am using a postbuild event that will copy the contents of localWeb.config or prodWeb.config to web.config. This works well but I was wondering if anyone knew of any better ways.

+1  A: 

I keep a single config file and use logic at runtime to detect of which subset of configuration to use. If the hostname is "prodsrvr-*" then I use the production server configuration, including db connections, etc. If the hostname is "test-*" then I use the test config data. And etc.

EDIT: here's some code that does what I described.

public static string GetConnString()
{
    string connString = ConfigurationSettings.AppSettings[GetConfigKey("database")];
    return connString;
}

public static string GetConfigKey(string baseKey)
{
    string str = baseKey;
    if (Dns.GetHostName().StartsWith("dinoch"))
    {
        str = str + "-dev";
    }
    else if (Dns.GetHostName().StartsWith("prodsrvr"))
    {
        str = str + "-prod";
    }
    return str;
}

<configuration>
   <appSettings>
     <add key="database-dev" value="server=(local)\vsdotnet;database=ASPXAPPS;Integrated Security=SSPI" />
     <add key="database-prod" value="server=(local)\vsdotnet;database=ASPXAPPS;Integrated Security=SSPI" />
   </appSettings>
</configuration>

I use a simple StartsWith() , with some "magic strings" hardcoded.

To avoid that, I could imagine defining a map of regex's to suffixes in the web.config file. Where, if regex1 is a match on the hostname, then use suffix1. If regex2, then use suffix2. Etc. You would load the map just once, and then just to a foreach() enumerating through the regex's and returning if they match the hostname.

Or, maybe there is a different criterion you want to use, to distinguish prod from dev from test servers, other than hostname. It's up to you.

Cheeso
This sounds like an approach I could use since it's mainly the connection strings that change for me. Could you please show me some code on how/where you do this?
codette
I can go with this only if the test and prod host name patterns are also in the web.config. Otherwise your stuck with magic strings in your source code, which is generally a no no (yea i'm guilty too).
jms
Yes, that's right. Magic strings.
Cheeso
+2  A: 

You could see if the method outlined on this CodeCarnage page suits your needs better. It utilizes the configsource attribute to point to DB and APP settings, each of which are seperated by environment. This could perhaps allow you to keep the consistent stuff in web.config and keep environment specific "stuff" in other config files.

JPrescottSanders
+1  A: 

this will continue to be a hack until asp.net 4 arrives http://www.asp.net/learn/whitepapers/aspnet40/#_Toc223325501

Pablote
+2  A: 

Check out the Web Deployment Tool:

Here are just a few of the tasks that be accomplished using the tool:

  1. Create a package that contains content, configuration and SQL databases for deployment or sharing with others.

  2. Use the package as a way to version your application or create backups.

  3. Add parameters to replace a connection string or other value in a file during install of a package.

  4. Enable non-administrators to deploy packages and granularly control their access.

  5. Synchronize or migrate both sites and servers running IIS 6.0 and IIS 7.0.

John Saunders