Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

How To Create a Custom ASP.NET Configuration Section Handler in Visual C# .NET


View products that this article applies to.

Summary

This article describes how to use Visual C# .NET to create a custom configuration section handler for ASP.NET.

Create the Configuration Section Handler and Its Components

These steps demonstrate how to create the configuration section handler and its components. So that you can better maintain and reuse the code, these steps demonstrate how to create a class named ConfigHelper that includes static methods. These static methods help you parse and retrieve the XML attributes in the configuration file. Because the code to build ConfigHelper uses an enumeration and a string in the configuration section, ConfigHelper contains two methods, GetEnumValue and GetStringValue.

The GetEnumValue method parses the configuration section for an attribute with predefined values, verifies that the value of the attribute is valid, and then returns the attribute and its value. The GetStringValue method parses the configuration section for an attribute and then returns the attribute and its value.
  1. Start Microsoft Visual Studio .NET.
  2. On the File menu, point to New, and then click Project.
  3. In the New Project dialog box, click Visual C# Projects under Project Types, and then click Class Library under Templates. In the Name text box, type MyConfig, and then click OK.
  4. Add a reference to the System.Web.dll assembly.
  5. Rename Class1.cs as MyConfig.cs.
  6. From Solution Explorer, open MyConfig.cs.
  7. Add the following namespace declarations to the top of the file:
    using System.Configuration;
    using System.Web;
    using System.Xml;
    					
  8. Delete the default class definition.
  9. Add an enumeration to hold an attribute for the custom configuration section:
    public enum LevelSetting
    {
       High,
       Medium,
       Low,
       None
    }
    					
  10. Create a class named MyConfigSection to hold the configuration information. This class is the object that the Create method implementation returns.
    public class MyConfigSection
    {
       private LevelSetting level = LevelSetting.None;
       private string name = "";
       public MyConfigSection(LevelSetting _level, string _name)
       {
          level = _level;
          name = _name;
       }
       public LevelSetting Level
       {
          get {return level;}
       }
       public string Name
       {
          get {return name;}
       }
    }
    					
  11. Create a class named ConfigHelper as follows:
    internal class ConfigHelper
    {
       //Helper method for retrieving enum values from XmlNode.
       public static XmlNode GetEnumValue
       (XmlNode _node, string _attribute,Type _enumType, ref int _val)
       {
          XmlNode a = _node.Attributes.RemoveNamedItem(_attribute);
          if(a==null)
             throw new ConfigurationException("Attribute required: " + _attribute);
          if(Enum.IsDefined(_enumType, a.Value))
             _val = (int)Enum.Parse(_enumType,a.Value);
          else
             throw new ConfigurationException("Invalid Level: '" + a.Value + "'",a);
          return a;
       }
       //Helper method for retrieving string values from xmlnode.
       public static XmlNode GetStringValue(XmlNode _node, string _attribute, ref string _val)
       {
          XmlNode a = _node.Attributes.RemoveNamedItem(_attribute);
          if(a==null)
             throw new ConfigurationException("Attribute required: " + _attribute);
          else
             _val = a.Value;
          return a;		
       }
    }
    						
    NOTE: You can also create a helper method for each data type for which you use your configuration section (for example, GetIntValue and GetBooleanValue).
  12. Create a class named MyConfigSectionHandler. This class inherits the IConfigurationSectionHandler interface and implements the Create method of that interface. In the Create method, this code uses the ConfigHelper class to retrieve the values from the configuration file. The sample then creates and returns the MyConfigSection object.

    The MyConfigSectionHandler class should appear as follows:
    public class MyConfigSectionHandler : IConfigurationSectionHandler
    {
       public virtual object Create(object parent,object configContext,XmlNode section)
       {
          int iLevel = 0;
          string sName = "";
    
          ConfigHelper.GetEnumValue(section, "level", typeof(LevelSetting), ref iLevel);
          ConfigHelper.GetStringValue(section, "name", ref sName);
          return new MyConfigSection((LevelSetting)iLevel,sName);
       }
    }
    					
  13. Save and compile the project.

Complete Code Listing

In its final form, your class file should appear as follows:
using System;
using System.Web;
using System.Xml;
using System.Configuration;

namespace MyConfig
{
   public enum LevelSetting
   {
      High,
      Medium,
      Low,
      None
   }
   public class MyConfigSectionHandler : IConfigurationSectionHandler
   {
      public virtual object Create(object parent,object configContext,XmlNode section)
      {
         int iLevel = 0;
         string sName = "";
		
         ConfigHelper.GetEnumValue(section, "level", typeof(LevelSetting), ref iLevel);
         ConfigHelper.GetStringValue(section,"name",ref sName);
         return new MyConfigSection((LevelSetting)iLevel,sName);
      }
   }
   public class MyConfigSection
   {
      private LevelSetting level = LevelSetting.None;
      private string name = null;
      
      public MyConfigSection(LevelSetting _level,string _name)
      {
         level = _level;
         name = _name;
      }
      public LevelSetting Level
      {
         get {return level;}
      }
      public string Name
      {
         get {return name;}
      }
   }
   internal class ConfigHelper
   {
      public static XmlNode GetEnumValue
      (XmlNode _node, string _attribute,Type _enumType, ref int _val)
      {
         XmlNode a = _node.Attributes.RemoveNamedItem(_attribute);
         if(a==null)
            throw new ConfigurationException("Attribute required: " + _attribute);
         if(Enum.IsDefined(_enumType, a.Value))
            _val = (int)Enum.Parse(_enumType,a.Value);
         else
            throw new ConfigurationException("Invalid Level",a);
         return a;
      }
      public static XmlNode GetStringValue(XmlNode _node, string _attribute, ref string _val)
      {
         XmlNode a = _node.Attributes.RemoveNamedItem(_attribute);
         if(a==null)
            throw new ConfigurationException("Attribute required: " + _attribute);
         else
            _val = a.Value;
         return a;		
      }
   }
}
				

Test the Configuration Handler

  1. Open Visual Studio .NET.
  2. In the New Project dialog box, click Visual C# Projects under Project Types, and click ASP.NET Web Application under Templates. Specify the name and location for your new project.
  3. Add a reference to MyConfig.dll.
  4. Open the Web.config file. Add the following code within the <configuration> section:
    <configSections>
       <sectionGroup name="system.web">
          <section name="myConfig" type="MyConfig.MyConfigSectionHandler,MyConfig" />
       </sectionGroup>
    </configSections>
    					
  5. Add the following code within the <system.web> section:
    <myConfig level="High" name="hello world" />
    					
  6. Open the code-behind file for WebForm1.aspx, which is named WebForm1.aspx.cs by default. Add the following namespace declaration to the top of WebForm1.aspx.cs:
    using MyConfig;
    					
  7. Add the following code to the Page_Load event. This code calls the GetConfig method to retrieve an instance of the MyConfigSection object and then writes out the values of the two properties of the object.
    MyConfigSection s = (MyConfigSection)Context.GetConfig("system.web/myConfig");
    Response.Write("Level: " + s.Level + "<br>");
    Response.Write("Name: " + s.Name);
    					
  8. Save and compile the application.
  9. View the page in the browser. The following output should appear:
    Level: High
    Name: hello world

Troubleshooting

When you create a custom ASP.NET configuration section handler, use the following guidelines when you implement the IConfigurationSectionHandler interface:
  • Instances of your class that implement the IConfigurationSectionHandler interface must be thread-safe and stateless. You must be able to call the IConfigurationSectionHandler.Create method from multiple threads simultaneously.
  • The configuration object that IConfigurationSectionHandler.Create returns must be thread-safe and immutable.
  • Do not modify the parent argument to IConfigurationSectionHandler.Create. Because the configuration system caches the configuration objects, it is important that you not modify the parent argument to IConfigurationSectionHandler.Create. For example, if the return value of IConfigurationSectionHandler.Create is only a small modification of the parent, you must modify a clone of the parent, not the original.

↑ Back to the top


References

For additional information about ASP.NET configuration, click the article numbers below to view the articles in the Microsoft Knowledge Base:
307626 INFO: ASP.NET Configuration Overview
307513 PRB: Access Violation Occurs When You Use a Custom Configuration Section Handler in an ASP.NET Application That Is Under Stress

↑ Back to the top


Keywords: KB309045, kbweb, kbhowtomaster, kbconfig

↑ Back to the top

Article Info
Article ID : 309045
Revision : 9
Created on : 7/15/2004
Published on : 7/15/2004
Exists online : False
Views : 462