Custom Configuration Sections in 3 Easy Steps

Are you tired of seeing your configuration settings as an endless list of key value pairs?

<add key="key0" value="value0" />
<add key="key1" value="value1" /> 
<add key="key2" value="value2" />
... 

Would you rather see something more like this?

<MySetting
  fileName="c:\temp"
  password="pencil"
  someOtherSetting="value" />

Join the club. Not only is the first approach prone to typos (AppSettings["tire"] or AppSettings["tier] anyone?), too many of these things all bunched together can cause your eyes to glaze over. It is a lot easier to manage when settings are grouped in logical bunches.

A while back Craig Andera solved this problem with the Last Configuration Section Handler he’d ever need. This basically made it easy to specify a custom strongly typed class to represent a logical group of settings using Xml Serialization. It led to a much cleaner configuration file.

But that was then and this is now. With ASP.NET 2.0, there’s an even easier way which I didn’t know about until Jeff Atwood recently turned me on to it.

So here is a quick run through in three easy steps.

Step one - Define your Custom Configuration Class

In this case, we’ll define a class to hold settings for a blog engine. We just need to define our class, inherit from System.Configuration.ConfigurationSection, and add a property per setting we wish to store.

using System;
using System.Configuration;

public class BlogSettings : ConfigurationSection
{
  private static BlogSettings settings 
    = ConfigurationManager.GetSection("BlogSettings") as BlogSettings;
        
  public static BlogSettings Settings
  {
    get
    {
      return settings;
    }
  }

  [ConfigurationProperty("frontPagePostCount"
    , DefaultValue = 20
    , IsRequired = false)]
  [IntegerValidator(MinValue = 1
    , MaxValue = 100)]
  public int FrontPagePostCount
  {
      get { return (int)this["frontPagePostCount"]; }
        set { this["frontPagePostCount"] = value; }
  }


  [ConfigurationProperty("title"
    , IsRequired=true)]
  [StringValidator(InvalidCharacters = "  ~!@#$%^&*()[]{}/;’\"|\\"
    , MinLength=1
    , MaxLength=256)]
  public string Title
  {
    get { return (string)this["title"]; }
    set { this["title"] = value; }
  }
}

Notice that you use an indexed property to store and retrieve each property value.

I also added a static property named Settings for convenience.

Step 2 - Add your new configuration section to web.config (or app.config).

<configuration>
  <configSections>
      <section name="BlogSettings" type="Fully.Qualified.TypeName.BlogSettings,   
      AssemblyName" />
  </configSections>
  <BlogSettings
    frontPagePostCount="10"
    title="You’ve Been Haacked" />
</configuration>

Step 3 - Enjoy your new custom configuration section

string title = BlogSettings.Settings.Title;
Response.Write(title); //it works!!!

What I covered is just a very brief overview to get you a taste of what is available in the Configuration API. I wrote more about configuration in the book I’m cowriting with Jeff Atwood, Jon Galloway, and K. Scott Allen.

If you want to get a more comprehensive overview and the nitty gritty, I recommend reading Unraveling the Mysteries of .NET 2.0 Configuration by Jon Rista.

Technorati Tags: , href="http://technorati.com/tags/Configuration">Configuration, href="http://technorati.com/tags/ASP.NET">ASP.NET

What others have said

Requesting Gravatar... David Mohundro Mar 12, 2007 5:25 AM
# re: Custom Configuration Sections in 3 Easy Steps
Thanks for sharing this!

I'd been wondering if it were possible to do something like this, because I never really cared for the name/value pair config settings.
Requesting Gravatar... LaptopHeaven Mar 12, 2007 5:50 AM
# re: Custom Configuration Sections in 3 Easy Steps
How can you provide Intellisense for custom configuration sections?
Requesting Gravatar... Tiernans Comms Closet Mar 12, 2007 6:14 AM
# Custom Configuration Sections
Check out this post over at You've Been Haacked showing you how to use custom configuration sections
Requesting Gravatar... engtech Mar 12, 2007 8:04 AM
# re: Custom Configuration Sections in 3 Easy Steps
I've started getting into using YAML serialization for configuration files.

Reading/writing is as simple as LoadFile/DumpFile and the structure of the config file matches the data structure used for the settings in the program.

http://www.yaml.org/
Requesting Gravatar... Bil Simser Mar 12, 2007 8:48 AM
# re: Custom Configuration Sections in 3 Easy Steps
Learn something new everyday! I'm like totally going to use this now. Thanks!
Requesting Gravatar... Rob Conery Mar 12, 2007 11:26 AM
# re: Custom Configuration Sections in 3 Easy Steps
You can also manipulate these settings from code, which provides a nice way for users to admin the config without editing yucky XML.

So given your example, you could do this:

// Get the current configuration file.
System.Configuration.Configuration config = WebConfigurationManager.OpenWebConfiguration(Request.ApplicationPath);

BlogSettings section = (BlogSettings )config.GetSection("BlogSettings ");

section.FrontPagePostCount=1000000;
config.Save();

We do just this for the CSK for the PayPal settings section and it's really a nice way to go.
Requesting Gravatar... Chris Mar 12, 2007 9:27 PM
# re: Custom Configuration Sections in 3 Easy Steps
Here is an even easier solution SCDL: http://blogs.msdn.com/dmitryr/archive/2005/12/07/501365.aspx. You write the sample custom configuration section to a txt file. You pass it into the SCDL.exe and tell it what you what the file output as (VB or C#) and the code file and the xsd file is auto generated.
# Custom Configuration in .NET 2.0
Custom Configuration in .NET 2.0
Requesting Gravatar... DotNetKicks.com Mar 13, 2007 5:09 PM
# Custom Configuration Sections in 3 Easy Steps
You've been kicked (a good thing) - Trackback from DotNetKicks.com
Requesting Gravatar... Benedikt Mar 14, 2007 5:18 AM
# re: Custom Configuration Sections in 3 Easy Steps
nice snippet,
especially the validator attribute.
Requesting Gravatar... mawi Mar 15, 2007 3:04 AM
# re: Custom Configuration Sections in 3 Easy Steps
This is still not what I want, and it is not what "the last configuration handler" does.

I think this is most readable:

<MyStuff type="SomeNamespace.MyStuff">
1234
<s>A bunch of information</s>
</MyStuff>

I dont like this as much:

<MyStuff
i="1234"
s="A bunch of information" />


Using the 2.0 config API to get elements is not nearly as nice, AFAIK. Ideas?
Requesting Gravatar... Development on a Shoestring Mar 18, 2007 2:28 AM
# Week in review (11-17 Mar 2007)
Firstly, Scott &amp;amp; Vivian had a new (as yet unnamed) baby girl.&amp;nbsp; Go say congratulations.
...
Requesting Gravatar... Stephan P. May 14, 2007 8:57 AM
# re: Custom Configuration Sections in 3 Easy Steps
What about a example for everyone interested about collections of elements as in:

<MyCustom>
<Persons>
<Person name="John" age="21" />
<Person name="Bill" age="34" />
<Person name="Dany" age="55" />
</Persons>
<AnotherCollectionOfItems>
<Item id="Item1" />
<Item id="Item2" />
<Item id="Item3" />
</AnotherCollectionOfItems>
</MyCustom>
Requesting Gravatar... Maureen May 17, 2007 12:45 PM
# re: Custom Configuration Sections in 3 Easy Steps
I would love to see an example that illustrates how to read a collection of elements.
Requesting Gravatar... Mikhail Diatchenko Aug 18, 2007 2:12 PM
# re: Custom Configuration Sections in 3 Easy Steps
Example that illustrates how to read a collection of elements:
http://msdn2.microsoft.com/en-us/library/system.configuration.configurationelement(VS.80).aspx
Requesting Gravatar... Mike Sep 13, 2007 9:07 AM
# re: Custom Configuration Sections in 3 Easy Steps
This code is a potential problem:

private static BlogSettings settings
= ConfigurationManager.GetSection("BlogSettings") as BlogSettings;

It is not certain what the name of the section will be. For example, here the name of the section is not what you expected:

<configuration>
<configSections>
<section name="BlogSection" type="Fully.Qualified.TypeName.BlogSettings,
AssemblyName" />
</configSections>
<BlogSettings
frontPagePostCount="10"
title="You’ve Been Haacked" />
</configuration>
Requesting Gravatar... Ben Oct 11, 2007 12:52 PM
# re: Custom Configuration Sections in 3 Easy Steps
In my case, this always returns NULL. private static BlogSettings settings
= ConfigurationManager.GetSection("BlogSettings") as BlogSettings;

I do not know why and havn't a clue how to troubleshoot it.

Requesting Gravatar... Mikhail Diatchenko Oct 17, 2007 10:30 PM
# re: Custom Configuration Sections in 3 Easy Steps
There are times when writing a custom configuration provider is an overkill, but working with AppSettings is not as elegant.

Solution? To write a wrapper class for app settings.

To speed things up I have written a simple tool to generate a wrapper class for app settings from Web.config or App.config - ClassFromConfig.

Check it out: http://wiki.webgear.co.nz/ClassFromConfig.ashx
Requesting Gravatar... connie segundo Nov 08, 2007 8:41 PM
# re: Custom Configuration Sections in 3 Easy Steps
i want to set up configuration
Requesting Gravatar... Muddxr Feb 12, 2008 1:30 AM
# re: Custom Configuration Sections in 3 Easy Steps
thats nice. it gives me new directions to work with configurations.
Requesting Gravatar... ASP Apr 25, 2008 4:29 AM
# re: Custom Configuration Sections in 3 Easy Steps
Great article!
Simple and straight to the point!
Thanks
Requesting Gravatar... Mike Gillson Jul 29, 2008 9:03 AM
# re: Custom Configuration Sections in 3 Easy Steps
I build a different type than your Fully.Qualified.TypeName.BlogSettings
My custom type implements the interface IConfigurationSectionHandler.
The interface defines one method. public object Create(object parent, object configContext, XmlNode section)
In this method I XmlNode, XmlNodeList, XPath to find things. I can do any XML processing I want. I do not have to use ConfigurationProperty attributes. The type is easy to extend whenever I need more configuration info.
I am just starting to build up my web site. Within a week, I plan to have an example for this type of configuration.
Requesting Gravatar... Chris Jul 31, 2008 8:13 PM
# re: Custom Configuration Sections in 3 Easy Steps
Mike, you shouldn't be using the IConfigurationSectionHandler. That's been deprecated since .Net 2.0. The current official mechanism is to inherit from ConfigSection.
Requesting Gravatar... Abouzar Dastmalchi Sep 23, 2008 12:52 PM
# re: Configuration Sections in 3 Easy Steps - TypeInitializationException
SOME ONE PLEAAAAAASE HELP ME with this simple project.

I've put this simple program into a Console Application. My App.config and BlogSettings.cs are copy paste of what Phil wrote but I get this frustrating exception all the time:

TypeInitializationException was unhandled: The type initializer for 'BlogSettings' threw an exception.

this happens when I run this line:
>>string title = BlogSettings.Settings.Title;

Any ideas?? Did anyone try this sample in a non-web-application environment??

I need to do this for a Windows service and been stuck at this error no matter what I do.

Many thanks in advance.

Requesting Gravatar... Paul Oct 15, 2008 8:06 AM
# re: Custom Configuration Sections in 3 Easy Steps
It looks like you must have the type wrong in your custom configuration settings definition. Make sure that the type is fully qualified ex
type="MyNamespace.MyclassName, MyAssembly"
Requesting Gravatar... E. Rolnicki Dec 29, 2008 8:59 AM
# re: Custom Configuration Sections in 3 Easy Steps
Any idea how to implement the attribute configSource=""?

the above would then become
<BlogSettings configSource="externalBlogSettings.config" />
Requesting Gravatar... Paul Juenger Dec 30, 2008 3:08 PM
# re: Custom Configuration Sections in 3 Easy Steps
I'm working on an ASP.NET MVC (beta) application where one of my controllers pulls a domain value from a custom configuration section. This works fine when I run the application, but when I run a unit test to against the controller it throws an exception because ConfigurationManager.GetSection("foo") is null. I also noticed that the appSettings collection is null, but the connectionString collection is initialized. Might this be a bug or am I missing something with MSTest?
Requesting Gravatar... Bill Mild Jan 15, 2009 7:56 AM
# re: Custom Configuration Sections in 3 Easy Steps
Is the book done?
Requesting Gravatar... rk Mar 03, 2009 6:05 AM
# re: Custom Configuration Sections in 3 Easy Steps
can we save the setting back to the config file too?
Requesting Gravatar... sezhian Feb 18, 2010 7:37 PM
# How to embed new connection string in vb.net
this is sezhian, i have an access database which shows the information abt the ledger name and database name .
then using this i should connect to sqlserver database .
There was an problem with connection string intializion error.
Pls help me
Requesting Gravatar... Bjorn Jun 09, 2010 1:00 AM
# re: Custom Configuration Sections in 3 Easy Steps
Hi

I get the following exception when I try to assign a value to a configuration property


Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Configuration.ConfigurationErrorsException: The configuration is read only.

Source Error:


Line 20: {
Line 21: get { return (string)this["serverIP"]; }
Line 22: set { this["serverIP"] = value; }
Line 23: }
Line 24:


Requesting Gravatar... Bret Jul 30, 2010 2:57 PM
# re: Custom Configuration Sections in 3 Easy Steps
By doing this, you lose the functionality of <add> that lets you override app.config settings at the machine.config and other hierarchical levels.

What do you have to say?

(will show your gravatar)
Please add 2 and 1 and type the answer here: