posted on Tuesday, November 28, 2006 1:25 PM by swarren

Reading a config section from an external file in ASP.NET 2.0

In my current project, we have a requirement to store some of the application settings in separate files from web.config.  Some application settings will change often enough that we'd like to export them from a forever-behind-the-firewall database to a file we can drop into the public website.  On the other hand the basic web.config settings will rarely change, and it could really mess up the application if the autogen'd settings somehow stomped an important configuration value in web.config.  Keeping these two kinds of settings in separate files helps make this approach viable.

As it turns out, this particular application uses three different mechanisms for referencing settings in an external file, so I've had a chance to compare and contrast the approaches.

1.  <appSetting>'s file= attribute.

2.  Any config section's configSource= attribute.

3.  A custom config section of type System.Configuration.AppSettingsSection.  This is essentially the same mechanism as #1, but you can create as many separate configuration files as you need using custom sections.


 

<appSetting>'s file=

The <appSetting> file mechanism is both simple and flexible, and probably "enough" for most ASP.NET 2.0 applications that need an external settings file.  The AppSettingsSection class allows supports loading settings from both an external file as well as declaring them inline in web.config:

In web.config:

<appSettings file="moresettings.config">
    <add key="first" value="inline settings are loaded before external ones" />
</appSettings>

In moresettings.config:

<appSettings>
    <add key="second" value="another setting" />
    <add key="third" value="yet another setting" />
</appSettings>


Notes:

  • the ACLs of the moresettings.config file must allow the ASP.NET application to read it
  • the root node of the moresettings.config file must be <appSettings>
  • key/value pairs declared inline in web.config appear first in the resulting NameValueCollection


Using the settings in code is easy:


using System.Configuration;
...
string first = ConfigurationManager.AppSettings["first"] as string;

When you access appSettings in code, all of the settings are members of the same collection despite being declared in separate files.  Your application could use this mechanism alone to segregate specific application-scoped settings to another file.

 

<urlMapping>'s configSource=

The configSource attribute can be used to specify an external source file for any ASP.NET 2.0 config section.  Unlike the file attribute, there's no merging of config settings between web.config and the external configuration file; you must move the entire section to a separate file.  The section tag (in this case <urlMappings>) must be the root element of the external file.

In web.config:

<urlMappings configSource="friendlyurls.config" />

In friendlyurls.config:

<urlMappings>
    <clear />
    <add url="~/Home.aspx" mappedUrl="~/Default.aspx?tab=home" />
</urlMappings>

 

Custom config section using System.Configuration.AppSettingsSection

There is plenty of documentation on MSDN for creating custom config section handlers in code, and in cases where you want to parse custom XML tags the full metal approach makes sense.  But if you just need another group of key/value pairs it's much simpler to use the existing System.Configuration.AppSettingsSection class.  This is the same class used for <appSettings> so it has the added benefit of permitting you to merge inline and external settings into a single KeyValueConfigurationCollection at runtime.

In web.config:

<configSections>
    <section name="regions" type="System.Configuration.AppSettingsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false" />
</configSections>

<regions file="regions.config">
    <add key="BE" value="Europe" />
</regions >

In regions.config:

<appSettings>
    <add key="US" value="North America" />
    <add key="CA" value="North America" />
</appSettings>

 

Reading the settings from a custom AppSettingsSection is more work than from the default AppSettings section.  And web.config heirarchies and the WebConfigurationManager.OpenWebConfiguration() method are just flexible enough to make grabbing the right instance of your web.config a little tricky.  I found the documentation and sample in the ASP.NET Quickstarts helpful in decyphering the options.  Here's some code that reads settings from a custom AppSettingsSection in the current application's root web.config:

using System.Configuration;
using System.Diagnostics;
using System.Web;
using System.Web.Configuration;

...

// Determine web path of the application's web.config
string path = HttpContext.Current.Request.CurrentExecutionFilePath;
path = path.Substring(0, path.LastIndexOf('/'));
if (path.Length == 0)
    path = "/";

// Open the config section as an AppSettingsSection
Configuration rootWebConfig = WebConfigurationManager.OpenWebConfiguration(path);
AppSettingsSection regionSection = rootWebConfig.GetSection("regions") as AppSettingsSection;

if (regionSection != null)
{
    // Get the appSettings key/value pairs collection
    KeyValueConfigurationCollection regionSettings = regionSection.Settings;

    foreach (KeyValueConfigurationElement item in regionSettings)
    {
        Debug.WriteLine("key: " + item.Key.ToString());
        Debug.WriteLine("value: " + item.Value.ToString());
    }
}

Comments

# re: Reading a config section from an external file in ASP.NET 2.0

Sunday, February 18, 2007 7:15 AM by Steve
Can this be done with the connectionStrings as well?

# re: Reading a config section from an external file in ASP.NET 2.0

Monday, February 19, 2007 2:35 PM by roni
great, thanks for sharing this with us :-)
gone use this on our website soon for direct access: http://www.indeXus.Net/swiss
instead of lazy querystring parameters.

cheers,
roni

# re: Reading a config section from an external file in ASP.NET 2.0

Monday, May 14, 2007 5:54 AM by Sanjay M
Wow I sure was confused about using an external file for log4net, and this post clarified things a LOT for me... a BIG THANKS :)

Now I know to add...

<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>

and also another entry


<log4net file="ecomm.log.config" />

And then in the ecomm.log.config file, I can just have the usual log4net section.

Thanks again.

The other alternative I had (and wanted to avoid) was to put in the name of the config file in the call to the configurator like

log4net.Config.XmlConfigurator.Configure(new FileInfo("ecomm.log.config"))

Now I can just use
log4net.Config.XmlConfigurator.Configure()

...like I wanted to!

Also another learning I'd like to share is that Id wanted both appsettings and log4net entries to be in the same external file but thats not possible, they need to be in different files because the config file can have only one root element.

# re: Reading a config section from an external file in ASP.NET 2.0

Saturday, September 15, 2007 1:36 PM by Slobodan J.
I agree with Sanjay M., this is good article but he also made mistake regarding referencing external config file (for log4net settings).
Instead of
<log4net file="ecomm.log.config" />
you should use this
<log4net configSource="ecomm.log.config" />

Regards

Slobodan

# re: Reading a config section from an external file in ASP.NET 2.0

Tuesday, October 02, 2007 7:12 PM by nick
wow, this is an interesting approach. thank you kindly for the insight

# re: Reading a config section from an external file in ASP.NET 2.0

Tuesday, October 16, 2007 2:54 PM by Ankit Agrawal
After creating the ConnectionString node in Web.Config file (ASP.NET 2005) even after import System.Configuration

I am not able ot see the ConfigurationManager as a class, so that I can read the node for creating a DB connection. Any advice is appreciated. Thanks.

# re: Reading a config section from an external file in ASP.NET 2.0

Monday, November 12, 2007 3:36 PM by Alok Ranjan
Good handy code to store/read key/value pairs in a config file..

Thank you...