HOW TO: Create a Custom ASP.NET Configuration Section Handler in Visual Basic .NET (318457)



The information in this article applies to:

  • Microsoft ASP.NET (included with the .NET Framework) 1.0
  • Microsoft Visual Basic .NET (2002)
  • Microsoft ASP.NET (included with the .NET Framework 1.1)
  • Microsoft Visual Basic .NET (2003)

This article was previously published under Q318457
For a Microsoft Visual C# .NET version of this article, see 309045.

This article refers to the following Microsoft .NET Framework Class Library namespaces:
  • System.Configuration
  • System.Enum
  • System.Xml

IN THIS TASK

SUMMARY

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

back to the top

Create the Configuration Section Handler and Its Components

These steps demonstrate how to create the configuration section handler and its components. These steps demonstrate how to create a class that is named ConfigHelper that includes static methods, so that you can better maintain and reuse the code. These static methods help you to parse and to retrieve the XML attributes in the configuration file. Because the code to build the ConfigHelper class uses an enumeration and a string in the configuration section, the ConfigHelper class contains two methods that are named 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 Basic Projects under Project Types, and then click Class Library under Templates.
  4. In the Name box, type MyConfig, and then click OK.
  5. Add a reference to the System.Web.dll assembly.
  6. Rename Class1.vb to MyConfig.vb.
  7. In Solution Explorer, open MyConfig.vb.
  8. Add the following namespace declarations to the top of the file:
    Imports System.Configuration
    Imports System.Web
    Imports System.Xml
    Imports System.Enum
    					
  9. Delete the default class definition.
  10. Create a namespace that is named MyConfig:
    Namespace MyConfig
         ' Code in the remaining steps will go in this namespace block.
    End Namespace
    					
  11. Add an enumeration to hold an attribute for the custom configuration section:
    Public Enum LevelSetting
        High = 3
        Medium = 2
        Low = 1
        None = 0
    End Enum
    					
  12. Create a class that is named MyConfigSection to hold the configuration information. This class is the object that the Create method implementation returns:
    Public Class MyConfigSection
        Private mylevel As LevelSetting = LevelSetting.None
        Private myname As String = ""
    
        Public Sub New(ByVal configLevel As LevelSetting, ByVal configName As String)
            mylevel = configLevel
            myname = configName
        End Sub
    
        Public ReadOnly Property Level() As LevelSetting
            Get
                Return mylevel
            End Get
        End Property
    
        Public ReadOnly Property Name() As String
            Get
                Return myname
            End Get
        End Property
    End Class
    					
  13. Create a class that is named ConfigHelper:
    Friend Class ConfigHelper
        Public Shared Function GetEnumValue(ByVal node As XmlNode, _
                                            ByVal attribute As String, _
                                            ByVal enumType As Type, _
                                            ByRef val As Integer) As XmlNode
    
            Dim a As XmlNode = node.Attributes.RemoveNamedItem(attribute)
            If (a Is Nothing) Then
                Throw New ConfigurationException("Attribute required: " + attribute)
            End If
    
            If IsDefined(enumType, a.Value) Then
                val = CType(Parse(enumType, a.Value), Integer)
            Else
                Throw New ConfigurationException("Invalid Level: '" + a.Value + "'", a)
            End If
    
            Return a
        End Function
    
        Public Shared Sub GetStringValue(ByVal node As XmlNode, _
                                         ByVal attribute As String, _
                                         ByRef val As String)
            Dim a As XmlNode = node.Attributes.RemoveNamedItem(attribute)
            If (a Is Nothing) Then
                Throw New ConfigurationException("Attribute required: " + attribute)
            Else
                val = a.Value
            End If
    
        End Sub
    End Class
    					
    NOTE: You can also create a helper method for each data type for which you use your configuration section (for example, GetIntValue and GetBooleanValue).

  14. Create a class that is 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 is:
    Public Class MyConfigSectionHandler
        Implements IConfigurationSectionHandler
    
        Friend Function Create(ByVal parent As Object, _
                               ByVal configContext As Object, _
                               ByVal section As XmlNode) As Object _
                Implements IConfigurationSectionHandler.Create
    
            Dim configLevel As Integer = 0
            Dim configName As String = ""
            Dim l As LevelSetting
    
            ConfigHelper.GetEnumValue(section, "level", l.GetType(), configLevel)
            ConfigHelper.GetStringValue(section, "name", configName)
    
    
            Return New MyConfigSection(CType(configLevel, LevelSetting), configName)
        End Function
    End Class
    					
  15. Save and then compile the project.


back to the top

Complete Code Listing

In its final form, your class file is:
Imports System
Imports System.Web
Imports System.Xml
Imports System.Configuration
Imports System.Enum

Namespace MyConfig

Public Enum LevelSetting
    High = 3
    Medium = 2
    Low = 1
    None = 0
End Enum

Public Class MyConfigSectionHandler
    Implements IConfigurationSectionHandler

    Friend Function Create(ByVal parent As Object, _
                           ByVal configContext As Object, _
                           ByVal section As XmlNode) As Object _
        Implements IConfigurationSectionHandler.Create

        Dim configLevel As Integer = 0
        Dim configName As String = ""
        Dim l As LevelSetting

        ConfigHelper.GetEnumValue(section, "level", l.GetType(), configLevel)
        ConfigHelper.GetStringValue(section, "name", configName)


        Return New MyConfigSection(CType(configLevel, LevelSetting), configName)
    End Function
End Class

Public Class MyConfigSection
    Private mylevel As LevelSetting = LevelSetting.None
    Private myname As String = ""

    Public Sub New(ByVal configLevel As LevelSetting, _
                   ByVal configName As String)
        mylevel = configLevel
        myname = configName
    End Sub

    Public ReadOnly Property Level() As LevelSetting
        Get
            Return mylevel
        End Get

    End Property

    Public ReadOnly Property Name() As String
        Get
            Return myname
        End Get
    End Property
End Class

Friend Class ConfigHelper
    Public Shared Function GetEnumValue(ByVal node As XmlNode, _
                                        ByVal attribute As String, _
                                        ByVal enumType As Type, _
                                        ByRef val As Integer) As XmlNode
        Dim a As XmlNode = node.Attributes.RemoveNamedItem(attribute)
        If (a Is Nothing) Then
            Throw New ConfigurationException("Attribute required: " + attribute)
        End If

        If IsDefined(enumType, a.Value) Then
            val = CType(Parse(enumType, a.Value), Integer)
        Else
            Throw New ConfigurationException("Invalid Level: '" + a.Value + "'", a)
        End If

        Return a
    End Function

    Public Shared Sub GetStringValue(ByVal node As XmlNode, _
                                     ByVal attribute As String, _
                                     ByRef val As String)
        Dim a As XmlNode = node.Attributes.RemoveNamedItem(attribute)
        If (a Is Nothing) Then
            Throw New ConfigurationException("Attribute required: " + attribute)
        Else
            val = a.Value
        End If
    End Sub
End Class

End Namespace
				
back to the top

Test the Configuration Section Handler

  1. Start Visual Studio .NET.
  2. In the Add New Project dialog box, click Visual Basic Projects under Project Types, and then 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 in the <configuration> section:
    <configSections>
       <sectionGroup name="system.web">
          <section name="myConfig" type="MyConfig.MyConfigSectionHandler,MyConfig" />
       </sectionGroup>
    </configSections>
    					
  5. Add the following code in the <system.web> section:
    <myConfig level="High" name="hello world" />
    					
  6. Open the code-behind file for WebForm1.aspx. By default, this is named WebForm1.aspx.vb. Add the following namespace declaration to the top of WebForm1.aspx.vb:
    Imports 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 the values of the two properties of the object:
    Dim s As MyConfigSection = CType( _
            Context.GetConfig("system.web/myConfig"), _
            MyConfigSection)
    
    Response.Write("Level: " + s.Level.ToString + "<br>")
    Response.Write("Name: " + s.Name)
    					
  8. Save and then compile the program.
  9. View the page in the browser. The following output appears:

    Level: High
    Name: hello world

back to the top

Troubleshooting

Use the following guidelines to implement the IConfigurationSectionHandler interface when you create a custom ASP.NET configuration section handler:
  • 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 the IConfigurationSectionHandler.Create method returns must be thread-safe and immutable.
  • Do not modify the parent argument to the IConfigurationSectionHandler.Create method. Because the configuration system caches the configuration objects, it is important not to modify the parent argument to the IConfigurationSectionHandler.Create method. For example, if the return value of the IConfigurationSectionHandler.Create method 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 number below to view the article 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

Modification Type:MajorLast Reviewed:6/17/2003
Keywords:kbConfig kbHOWTOmaster kbweb KB318457 kbAudDeveloper