Microsoft KB Archive/318457

= HOW TO: Create a Custom ASP.NET Configuration Section Handler in Visual Basic .NET =

Article ID: 318457

Article Last Modified on 6/17/2003

-

APPLIES TO


 * Microsoft ASP.NET 1.0
 * Microsoft Visual Basic .NET 2002 Standard Edition
 * Microsoft ASP.NET 1.1
 * Microsoft Visual Basic .NET 2003 Standard Edition

-



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
 * Create the Configuration Section Handler and Its Components
 * Complete Code Listing
 * Test the Configuration Section Handler
 * Troubleshooting

REFERENCES



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.  Start Microsoft Visual Studio .NET. On the File menu, point to New, and then click Project. In the New Project dialog box, click Visual Basic Projects under Project Types, and then click Class Library under Templates. In the Name box, type MyConfig, and then click OK. Add a reference to the System.Web.dll assembly. Rename Class1.vb to MyConfig.vb. In Solution Explorer, open MyConfig.vb.</li>  Add the following namespace declarations to the top of the file: Imports System.Configuration Imports System.Web Imports System.Xml Imports System.Enum </li> Delete the default class definition.</li>  Create a namespace that is named MyConfig: Namespace MyConfig ' Code in the remaining steps will go in this namespace block. End Namespace </li>  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 </li>  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 = &quot;&quot;

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 </li>  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(&quot;Attribute required: &quot; + attribute) End If

If IsDefined(enumType, a.Value) Then val = CType(Parse(enumType, a.Value), Integer) Else Throw New ConfigurationException(&quot;Invalid Level: '&quot; + a.Value + &quot;'&quot;, 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(&quot;Attribute required: &quot; + 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).

</li>  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 = &quot;&quot; Dim l As LevelSetting

ConfigHelper.GetEnumValue(section, &quot;level&quot;, l.GetType, configLevel) ConfigHelper.GetStringValue(section, &quot;name&quot;, configName)

Return New MyConfigSection(CType(configLevel, LevelSetting), configName) End Function End Class </li> Save and then compile the project.</li></ol>

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 = &quot;&quot; Dim l As LevelSetting

ConfigHelper.GetEnumValue(section, &quot;level&quot;, l.GetType, configLevel) ConfigHelper.GetStringValue(section, &quot;name&quot;, 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 = &quot;&quot;

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(&quot;Attribute required: &quot; + attribute) End If

If IsDefined(enumType, a.Value) Then val = CType(Parse(enumType, a.Value), Integer) Else Throw New ConfigurationException(&quot;Invalid Level: '&quot; + a.Value + &quot;'&quot;, 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(&quot;Attribute required: &quot; + attribute) Else val = a.Value End If   End Sub End Class

End Namespace back to the top

Test the Configuration Section Handler
<ol> Start Visual Studio .NET.</li> 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.</li> Add a reference to MyConfig.dll.</li>  Open the Web.config file. Add the following code in the section: <configSections> <sectionGroup name=&quot;system.web&quot;> <section name=&quot;myConfig&quot; type=&quot;MyConfig.MyConfigSectionHandler,MyConfig&quot; /> </sectionGroup> </configSections> </li>  Add the following code in the <system.web> section: <myConfig level=&quot;High&quot; name=&quot;hello world&quot; /> </li>  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 </li>  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(&quot;system.web/myConfig&quot;), _        MyConfigSection)

Response.Write(&quot;Level: &quot; + s.Level.ToString + &quot; &quot;) Response.Write(&quot;Name: &quot; + s.Name) </li> <li>Save and then compile the program.</li> <li>View the page in the browser. The following output appears:

Level: High

Name: hello world

</li></ol>

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

<div class="references_section">