Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ASP.NET Custom Web Configuration Section

0.00/5 (No votes)
18 Jan 2009 2  
Learn how to define and use your own web.config sections for code libraries.

Introduction

The web.config can be a very useful tool in web development. It allows you to place settings that can be accessed by your website and changed without having to re-deploy your code. But, what happens when you want to build a code library and have the web.config settings for the library? Sure, you can use the standard <appSettings> section, but there is another way. You can create a custom web.config section.

Background

I believe it is important to make everything (within reason) reusable. Anything you would use on more than one project should be placed into a reusable code library. Anything you want to Unit Test or run through FXCop should be in its own class library. Also, I believe that these code libraries should have a way to change their settings to make them usable in multiple scenarios.

But, what if you have a library that could be used in both ASP.NET websites and Windows applications? If you use System.Configuration.ConfigurationManager.AppSettings["Key"], it will actually refer to the same key in either the web.config or app.config. That is a very simple and easy way to do it, but this article is about making a custom web configuration. I have not tested it, but this custom section may or may not work in the application configuration. This article will focus on the use of the custom configuration in a web environment.

Define the Attributes

The first step is to determine what settings you want to expose. Once you are sure you know what you want to expose, it is time to create the ConfigurationSection definition class. In the case of my caching library, I called it CacheConfiguration. Note that it must extend from System.Configuration.ConfigurationSection.

public class CacheConfiguration : ConfigurationSection

Next is defining the attributes. For this class, I am exposing integer values corresponding to lengths of time in sections to associate with a cache priority. Shown below is a sample of one of the attributes:

// Number Property
[ConfigurationProperty("highPriority", DefaultValue = 60, IsRequired = false)]
[IntegerValidator(MinValue = 0)]
public int HighPriority
{
    get
    { return (int)this["highPriority"]; }
}

ConfigurationProperty is a definition of the attribute, including the name, default value, and whether or not the attribute is required. IntegerValidator allows me to define the minimum value, which is zero in this case.

Once thing you should be aware of is that the attribute name (highPriority) is case sensitive when placed in the web.config.

Access the Attributes

To make things easier on myself, I create a Configuration class that acts as a wrapper around the configuration section. This exposes the properties more easily with a simple reference to a static class, rather than having to create an instance of the config section each time it needs to be accessed.

public static class Configuration
{
    public static CacheConfiguration CacheConfiguration
    {
        get
        {
            CacheConfiguration config = (CacheConfiguration)
              System.Configuration.ConfigurationManager.GetSection("olympus/cache");

            return config;
        }
    }
}

Did you notice the node declaration? The string parameter "olympus/cache" tells GetSection what node my attributes are in. If I wanted to place my config inside <system.web>, I could change it to "system.web/cache". I prefer to have my section in its own wrapper.

Web.Config - Declare the Section

<configuration>
    <configSections>
    <sectionGroup name="olympus">
      <section name="cache" type="Olympus.Caching.CacheConfiguration" 
        allowLocation="true" allowDefinition="Everywhere"/>
    </sectionGroup>
</configSections>
...

Below the <configSections> block, inside <configuration> and not in <system.web>, place the attributes with their values.

<olympus>
    <cache highPriority="360"  />
</olympus>

Element Collections

So, now that you have a basic understanding of custom configurations, let's move on to something a bit more advanced. What if you wanted a collection of elements, such as a collection of cookies used by your site? Well, with an additional class and a few modifications, you can make a web.config section that looks like this:

<olympus>
    <cookie>
      <cookies>
        <add name="My_Cookie_1" enableEncryption="true" timeout="4200" />
        <add name="My_Cookie_2" enableEncryption="true" timeout="4200" />
      </cookies>
    </cookie>
</olympus>

All we need to do is add a ConfigurationElementCollection class to wrap the ConfigurationSection into a collection. I have a class already built that handles cookies encrypted with Rijndael, Triple DES, or DES (user's choice), but encryption and cookies are topics for another day.

public class CookieConfig : ConfigurationSection

CookieConfig is the class that contains the attributes. This corresponds identically to CacheConfiguration.

public class CookieCollectionConfiguration : ConfigurationElementCollection
{

    public CookieConfig this[int index]
    {
        get
        {
            return base.BaseGet(index) as CookieConfig;
        }
        set
        {
            if (base.BaseGet(index) != null)
            {
                base.BaseRemoveAt(index);
            }
            this.BaseAdd(index, value);
        }
    }

    public CookieConfig this[string name]
    {
        get
        {
            return base.BaseGet(name) as CookieConfig;
        }
        set
        {
            int index = -1;
            if (base.BaseGet(name) != null)
            {
                index = base.BaseIndexOf(base.BaseGet(name));
                base.BaseRemove(name);
            }

            if (index == -1)
            {
                this.BaseAdd(value);
            }
            else
            {
                this.BaseAdd(index, value);
            }
        }
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new CookieConfig();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((CookieConfig)element).Name;
    } 
}

So, there you have it, custom web.configuration sections for your code libraries. I recommend creating an example of the web.config section with all fields defined and including the file in the code library project. This will make it easy to figure out how to use your custom configuration when adding the library to a new web application. One of the issues with a custom section is that you only have the documentation you create, and there is no intellisense support.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here