Best Practices for Configuring ASP.NET ConnectionStrings and AppSettings in Web.Config

The Typical Way

When you first create an asp.net project a file is usually created in your root web directory called web.config.  By default there are two (usually empty) sections in the file.  One for appSettings, and one for connectionStrings.  Below is a default project created with visual studio 2008 and a sample web.config file.

webconfig1

The thing you would normally do is put stuff in those tags that your application would use.  That is, you would would likely put in a sqlserver connection in the connection tag, then in your appsettings section, you might put something like your smtp mail server location.  Here is what this might look like after you have configured your settings.

  <appSettings>
    <add key="UseCache" value="True"/>
    <add key="MapsKey" value="1234567890-AA"/>
    <add key="SMTPServer" value="smtp.peterkellner.net"/>
  </appSettings>

  <connectionStrings>
    <clear/>
    <add name="LocalSqlServer"
          connectionString="Data Source=(local);Initial Catalog=aspnetdb;Integrated Security=True"
          providerName="System.Data.SqlClient" />
  </connectionStrings>

The problem with this approach is that when you deploy your application to a new server, you might want to change your SMTPServer in the AppSettings, and you might want to change your connection string in your ConnectionStrings section.  Usually what happens is that you have to have a separate web.config that you use for production.  The problem is, of course, that you have other things in your web.config that change as you build your application.  You may for example add a new page handler and this means you have to maintain one web.config for production and one for development and you have to modify both of them each time you change something.

A Better Way

A solution to this problem (though not the best so read on after this), is to extract appSettings and connectionStrings to a separate file on your server.  Then, you can leave those files on the server and not worry about those changing.  The way this looks is as follows.  You will now have three files to worry about.  web.config (which you had before), and two new files, webAppSettings.config and WebConnectionString.config.  Here are what these three files now look like.

Web.Config:

  <appSettings file="webAppSettings.config">
  </appSettings>

  <connectionStrings configSource="WebConnectionString.config">
  </connectionStrings>


  <system.web>
        <!-- 

WebAppSettings.config

<appSettings>
  <add key="UseCache" value="True"/>
  <add key="MapsKey" value="1234567890-AA"/>
  <add key="SMTPServer" value="smtp.peterkellner.net"/>
</appSettings>

WebConnectionString.config

<connectionStrings>
    <clear/>
    <add name="LocalSqlServer"
        connectionString="Data Source=(local);Initial Catalog=aspnetdb;Integrated Security=True"
        providerName="System.Data.SqlClient" />
</connectionStrings>

This actually works, but there is even a best way.

The Best Way

I didn’t realize it until Conrad Cady, a senior developer at our company pointed this out to me.  Basically, it turns out that you can put default values in your web.config AND also have the file= tag in the appSettings tag.  Unfortunately, this only works with AppSetting and the file tag.   For the connectionStrings, you can not have values inside the connectionString tag if you use the configSource attribute.  That is, you can create a web.config file that looks like the following:

<appSettings file="webAppSettings.config">
    <add key="UseCache" value="True"/>
    <add key="MapsKey" value="1234567890-AA"/>
    <add key="SMTPServer" value="smtp.peterkellner.net"/>
  </appSettings>

  <connectionStrings configSource="WebConnectionString.config">
  </connectionStrings>

What happens is that if you have values in your webAppSettings.config file, they will override what is in your web.config appSettings section. If you have no webAppSettings.config file, then all the values in web.config webAppSettings section are used.

connectionStrings unfortunately does not work the same.  You MUST have a WebConnectionString.config file for this setup and you MUST NOT have any values inside the connectionStrings tag in the web.config file.

How to Use the "Best Way" in Real Life

So, the title of this article is "Best Practices".  So, what is the best practice.  Well, IMHO the best practice is to have your production AppSettings in your web.config file and not have an external file checked into source control (that is, don’t check in webAppSettings.config).  Only create that file for development servers where you want to override you default (web.config) appSettings keys and attributes.  For connectionStrings, I recommend always using an external file but don’t actually check it into source control.  Instead, check in a file named WebConnectionString.config.sample and on each environment where you are running a web server, rename that file to WebConnectionString.config so that it will actually be used.  Again, the most important thing is NOT to check into source control a file called WebConnectionString.config or webAppSettings.config.  Both should have sample versions checked in, but not actual ones.  That way, you will avoid overwriting real ones when you check out your source control to a working directory.

About Peter Kellner

Follow me:


Comments

  1. João Paulo says:

    Really good info! Thank you for sharing it!

  2. very good work

  3. Paul Nersesov says:

    What if I need to have the ServerName as a reference from
    appSettings to to connectionStrings?

    add key=”ServerName” value=”GISWEBD.WORLD”
    add name=”Conn1″ connectionString=”Data Source=ServerName;

  4. Paul Nersesov says:

    Hi,
    What if I need to have the ServerName as a reference from
    to inside my web.config

    Thank you.

  5. This was actually what I was looking for, and I am glad to came here! Thanks for sharing the such information with us.

  6. samsul siregar says:

    I finally understand about how to write connectionString in web.config, thank you..!!!

  7. AmericanGopi says:

    Thank You So much I Love Peter

  8. Rob Rasner Wikipedia says:

    I’m really loving your idea/layout of one’s blog Best Practices for Configuring ASP.NET ConnectionStrings and AppSettings in Web.Config | PeterKellner.net , Will you actually face any kind of browser interface issues A small number of my blog visitors do complained about my blog not really operating correctly within Explorer but looks good within Safari. Have you got any kind of advice to assist resolve the problem? Before I forget our thoughts go out to everyone close by tsunami we hope you are well and secure too ?

  9. Good article. However, I was wondering if there was any way that we could perhaps take this a step further. Let’s say I have a set of connection string config files for each environment, Dev, Test and Prod. Is there a way for me to set up the web.config with some kind of environment variable that I can change so that the configSource will be able to read the correct connection config file for that environment?
    Example,
    whatEnvironment=”Dev”

    Thanks

  10. Great info I can definitly use this.
    Thanks.

  11. Thank you very much! I have been fighting this dang web.config all day! Now, I can move forward…

  12. PrashanthSpark says:

    How about when we want to encrypt our connection strings using security. Here I would rename Web.config.exe , in your above explaination , I would also need to rename weconnection.config.exe . Does this recognize!! Can we still use crypto encryption

  13. Hello, thank you for the article. I have separated my “connectionStrings” section out from the web.config into a new file called db.config, which works great, exactly as your article details. However, I find that I can no longer programmatically encrypt the connection strings on the server using the ConfigurationSection.SectionInformation.ProtectSection(…) method. (Actually, it does encrypt it, but then throws when I attempt to Save the configuration.) To complete your “Best Practices” article, I wonder how this would be possible to save such change to the secondary file. Thank you!

  14. the text dissappered…

  15. hi, maybe you can help me?

    the app is working fine, but now the smtp provider needs a login on the smtp server… how should this look?
    I have used these lines, but I can nt get it to work…

    in the appsettings in web.config:

    please advice and thank you in advance,
    Daniel, Sweden

  16. I am trying to split my main Web.config into 2 files like shown in best way. but getting my applcation stopped working and getting blank page. I am using .net 3.5. Does this “Best approach” works in .net 3.5?

  17. Tale was a runaway success. ,

  18. i’m getting following error with this.

    The format of a configSource file must be an element containing the name of the section.

    Can you tell me Why?

  19. one more try…

    <section name=”customSettings” type=”System.Configuration.NameValueFileSectionHandler,system, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″ />

  20. If you see the error “Unrecognized attribute ‘file’.”, you might be using the wrong handler.

    Make sure your section block uses the NameValueFileSectionHandler:

  21. I’m new about this topic and i would like to know how i could access into these config file from the class

    ConfigurationManager.ConnectionStrings(“LocalSqlServer”).ConnectionString??

    Thanks in advance

  22. Why not just use a Web Deployment Project? This handles all web.config section replacements based on the current solution configuration chosen.

  23. This is a great solution! Thanks for posting it!

    I’ve put it in place in a machine’s root directory as Mr.Vladimir suggested. Through some trial and error, I was even able to encrypt the config sections both internally and externally to the web.config file.

    One question arose as I was working in the C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG directory, though. The connection strings work effectively in both the web.config and the machine.config files at this level. Which file would be more appropriate for storing connection strings to be accessed globally in the server environment?

  24. Nice visual expalnation… thanks Peter

  25. Is your “A Better Way” no longer possible with the latest asp.net??? I’m getting an error “Unrecognized attribute ‘file’.”

    I specifically want the ‘overriding’ behavior pointed out by Conrad so I don’t want “The Best Way”. Any suggestions?

  26. Rob Reiss says:

    Thanks for the tip! Say hi to Conrad for me, I worked with him at RelayHealth. Rob Reiss

  27. Peter, my co-worker explained me that there is another and probably better (more secure) way to deal with connectionStrings (but not with appSettings!). You could remove connectionStrings from your application’s web.config and add it to your machine’s root web.config which is located under C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG

  28. That’s a good advice. Thank you, Peter!

  29. One note of caution – don’t ever put a config file with a .sample extension on your web server. ASP.NET won’t serve .config files, but it probably will serve .sample files, and you’ll expose your connection strings and other app settings to site visitors.

  30. Hey Now,
    Great Post, informative, quick & easy to understand.
    Thx 4 the info,
    Catto

  31. Really useful!
    Thanks.

  32. it would be nice to move those config files e.g. to the App_Data folder.

    i messed a bit with paths to get my configs into a folder but so far i wasnt lucky at all – any ideas to do something like

    file=”~App_Data/my.config” in the web.config ?

  33. Great tip, thanks for sharing. I had no idea that option was available.

  34. Peter Kellner says:

    Thanks Joel! you are right, that is what I meant. I think I confused myself. :)

  35. In the sentence near the end of the article:

    “If you have no webAppSettings.config file, then all the values in web.config webAppSettings.config file are used.”

    Do you mean: “…then all the values in web.config appSettings…”?

Trackbacks

  1. […] public bool Blah() { using (SqlConnection conn = new SqlConnection()) { SqlCommand cmd = new SqlCommand("sproc", conn); cmd.CommandType = CommandType.StoredProcedure; // add parameters cmd.Parameters.Add(new SqlParameter("@ID", SqlDbType.Int, int.MaxValue, ParameterDirection.Output)); conn.Open(); // *** GRAB output paramter here, how????????? cmd.ExecuteNonQuery(); int id = cmd.Parameters["@ID"].Value; conn.Close(); } } http://pietschsoft.com/post/2005/12/28/ASPNET-20-How-to-get-a-specific-ConnectionString-from-the-WebConfig-by-name.aspx http://peterkellner.net/2008/02/23/webconfigbestpractice/ […]

Follow

Get every new post delivered to your Inbox

Join other followers: