Best Practices for Configuring ASP.NET ConnectionStrings and AppSettings in Web.Config
Saturday 23 February 2008 @ 2:25 pm

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.





22 Responses to “Best Practices for Configuring ASP.NET ConnectionStrings and AppSettings in Web.Config”

  1. Joel Says:

    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…”?

  2. Peter Kellner Says:

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

  3. Speednet Says:

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

  4. Sascha Says:

    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 ?

  5. Carlos Eduardo Appel Klein - DigitalDesk Says:

    Really useful!
    Thanks.

  6. catto Says:

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

  7. Joel P Says:

    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.

  8. Vladimir Kelman Says:

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

  9. Vladimir Kelman Says:

    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

  10. Rob Reiss Says:

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

  11. Scott Says:

    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?

  12. NET Web Services Says:

    Nice visual expalnation… thanks Peter

  13. Mark Says:

    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?

  14. Larrybud Says:

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

  15. Victor Says:

    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

  16. Jeekue Says:

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

    Make sure your section block uses the NameValueFileSectionHandler:

  17. Jeekue Says:

    one more try…

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

  18. Ranjani Says:

    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. John95 Says:

    Tale was a runaway success. ,

  20. Jas Says:

    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?

  21. daniel Says:

    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

  22. daniel Says:

    the text dissappered…

Leave a Reply