Custom Configuration Sections in 3 Easy Steps

aspnet configuration 0 comments suggest edit

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 {.clear}

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.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

48 responses

  1. Avatar for David Mohundro
    David Mohundro March 11th, 2007

    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.

  2. Avatar for Courtney V. Bearse
    Courtney V. Bearse March 11th, 2007

    How can you provide Intellisense for custom configuration sections?

  3. Avatar for Tiernans Comms Closet
    Tiernans Comms Closet March 11th, 2007

    Check out this post over at You've Been Haacked showing you how to use custom configuration sections

  4. Avatar for engtech
    engtech March 11th, 2007

    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/

  5. Avatar for Bil Simser
    Bil Simser March 11th, 2007

    Learn something new everyday! I'm like totally going to use this now. Thanks!

  6. Avatar for Rob Conery
    Rob Conery March 12th, 2007

    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.

  7. Avatar for Chris
    Chris March 12th, 2007

    Here is an even easier solution SCDL: http://blogs.msdn.com/dmitr.... 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.

  8. Avatar for David Crowell :: Occasional Th
    David Crowell :: Occasional Th March 12th, 2007

    Custom Configuration in .NET 2.0

  9. Avatar for DotNetKicks.com
    DotNetKicks.com March 13th, 2007

    You've been kicked (a good thing) - Trackback from DotNetKicks.com

  10. Avatar for Benedikt
    Benedikt March 13th, 2007

    nice snippet,
    especially the validator attribute.

  11. Avatar for mawi
    mawi March 14th, 2007

    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?

  12. Avatar for Development on a Shoestring
    Development on a Shoestring March 17th, 2007

    Firstly, Scott &amp;amp; Vivian had a new (as yet unnamed) baby girl.&amp;nbsp; Go say congratulations.
    ...

  13. Avatar for Stephan P.
    Stephan P. May 13th, 2007

    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>

  14. Avatar for Maureen
    Maureen May 17th, 2007

    I would love to see an example that illustrates how to read a collection of elements.

  15. Avatar for Mikhail Diatchenko
    Mikhail Diatchenko August 18th, 2007

    Example that illustrates how to read a collection of elements:
    http://msdn2.microsoft.com/...

  16. Avatar for Mike
    Mike September 12th, 2007

    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>

  17. Avatar for Ben
    Ben October 11th, 2007

    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.

  18. Avatar for Mikhail Diatchenko
    Mikhail Diatchenko October 17th, 2007

    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/C...

  19. Avatar for connie segundo
    connie segundo November 8th, 2007

    i want to set up configuration

  20. Avatar for Muddxr
    Muddxr February 11th, 2008

    thats nice. it gives me new directions to work with configurations.

  21. Avatar for ASP
    ASP April 24th, 2008

    Great article!
    Simple and straight to the point!
    Thanks

  22. Avatar for Mike Gillson
    Mike Gillson July 28th, 2008

    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.

  23. Avatar for Chris
    Chris July 31st, 2008

    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.

  24. Avatar for Abouzar Dastmalchi
    Abouzar Dastmalchi September 23rd, 2008

    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.

  25. Avatar for Paul
    Paul October 14th, 2008

    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"

  26. Avatar for E. Rolnicki
    E. Rolnicki December 28th, 2008

    Any idea how to implement the attribute configSource=""?
    the above would then become
    <BlogSettings configSource="externalBlogSettings.config" />

  27. Avatar for Paul Juenger
    Paul Juenger December 30th, 2008

    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?

  28. Avatar for Bill Mild
    Bill Mild January 14th, 2009

    Is the book done?

  29. Avatar for rk
    rk March 2nd, 2009

    can we save the setting back to the config file too?

  30. Avatar for sezhian
    sezhian February 18th, 2010

    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

  31. Avatar for Bjorn Theart
    Bjorn Theart June 8th, 2010

    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:

  32. Avatar for Bret
    Bret July 30th, 2010

    By doing this, you lose the functionality of <add> that lets you override app.config settings at the machine.config and other hierarchical levels.

  33. Avatar for Visual C# Kicks
    Visual C# Kicks June 29th, 2011

    For anyone else who might be banging their head against the wall with this:
    name is for the tag-name in the app.config file, type is where the class name goes
    that took 30 minutes i'll never see again

  34. Avatar for Mary
    Mary August 23rd, 2011

    Thanks for the valuable info! :)

  35. Avatar for Orry Rotem
    Orry Rotem September 16th, 2011

    Ahhhh, exactly what i was looking for. Thanks Phil.
    Note: for dlls you can change the "config section getter" code from this:
    private static BlogSettings settings
    = ConfigurationManager.GetSection("BlogSettings") as BlogSettings;
    .. to this:
    private static BlogSettings settings
    = ConfigurationManager.OpenMappedExeConfiguration(New ExeConfigurationFileMap(Assembly.GetExecutingAssembly.Location & ".config"), ConfigurationUserLevel.None).GetSection("BlogSettings") as BlogSettings;


  36. Avatar for Charles
    Charles November 27th, 2012

    Hi.
    I've got an problem
    Dim title As String = BlogSettings.Settings.Title
    I receive an error:The type initializer for 'ReadCustomSectionAppConfig.BlogSettings' threw an exception.
    I try with Dim x As Object = ConfigurationManager.GetSection("BlogSettings")
    I receive an error: Could not find file ReadCustomSectionAppConfig\ReadCustomSectionAppConfig\bin\Debug\ReadCustomSectionAppConfig.vshost.exe.config line 5)
    Report the values ​​of assembly and root namespace of my window application
    assembly name:ReadCustomSectionAppConfig
    root namespace:ReadCustomSectionAppConfig

  37. Avatar for Mediin
    Mediin February 3rd, 2014

    The first comprehensible article on the whole topic. Probably the only on in the whole web.

  38. Avatar for Don Pablone
    Don Pablone June 2nd, 2015

    Thanks for this post, was very useful !!!

  39. Avatar for CentiPad
    CentiPad July 21st, 2015

    Been reading thousands of rows of incomprehensible explanations and it still does not work properly. But then there's you, being able to break down the subject into three simple steps and it just works instantly.

  40. Avatar for haacked
    haacked July 21st, 2015

    Thanks! Your comment made my day. :)

  41. Avatar for Giannis Demetriou
    Giannis Demetriou October 30th, 2015

    What if I want to create a List of objects? is there a simple and easy way similar to the one above?

  42. Avatar for Giannis Demetriou
    Giannis Demetriou October 30th, 2015

    I would love something similar to that

  43. Avatar for Mouli
    Mouli August 23rd, 2016

    Simply superb.

  44. Avatar for Fenil Desai
    Fenil Desai December 20th, 2016

    Can we pass another config section as parameter to a config section. something like -

    <blogsettings frontpagepostcount="10" title="You’ve Been Haacked" customsection="mysectionName"/>

    where mysectionname is another section -
    <section name="mysectionName" type="Fully.Qualified.TypeName.mysectionName,
    AssemblyName"/>

  45. Avatar for Chandan Kumar
    Chandan Kumar April 21st, 2017

    The above link "Unraveling the Mysteries of .NET 2.0 Configuration" is not correct. Here is the correct link :
    https://www.codeproject.com...

  46. Avatar for haacked
    haacked April 21st, 2017

    Thanks! I've updated the link. It should be fixed soon.

  47. Avatar for drumdumdum
    drumdumdum July 31st, 2017

    Thank you! Worked well.

  48. Avatar for Jayson Knight
    Jayson Knight September 27th, 2018

    11 years later, and this is still a go to post for me for wiring up simple configuration settings. Is there a new mechanism to do this though?