Recipe 9.6 Adding Your Own Configuration Elements to web.config

     

9.6.1 Problem

You want to create and add your own configuration elements to web.config . No predefined element will do, nor will use of the <appSettings> key / value entries of web.config , as described in Recipe 9.2.

9.6.2 Solution

Determine what configuration information you want to store in web.config , create your own custom section handler for parsing the element, add the definition of the section handler to web.config , add the new configuration element to web.config , and then use the configuration information in your application.

  1. Determine what configuration information you want to store in web.config .

  2. Use the .NET language of your choice to create a custom section handler class for parsing your newly defined element.

  3. Add the definition of the section handler to the <configSections> section of web.config .

  4. Add the new configuration element to web.config and assign values to its attributes or child elements.

  5. In the code-behind class for your ASP.NET page, use the .NET language of your choice to access and put the custom configuration data to work.

The code we've written to illustrate this solution appears in Example 9-9 through Example 9-14. Example 9-9 (VB) and Example 9-10 (C#) show the class for a custom section handler. The changes we've made to web.config to have it use the custom section handler are shown in Example 9-11. Example 9-12 shows the .aspx file for a sample web form that displays some custom configuration settings. Example 9-13 and Example 9-14 show the code-behind class that accesses the custom configuration information.

9.6.3 Discussion

Sometimes the predefined configuration elements provided by ASP.NET, including the key / value collection available through the <appSettings> element of web.config (described in Recipe 9.2) are not enough. When this is the case, being able to store any configuration information required by your application in its own custom section in web.config can be a useful alternative. What's more, having a custom section in web.config can be a real boon to program clarity and ease of implementation.

As a prelude to discussing the custom section for web.config , it's worthwhile reviewing the basic structure of a machine.config file, as shown next , because it is the machine.config file whose structure we will mimic . The root node of the XML document is <configuration> . The <configSections> child element is next. It defines the configuration section elements that will follow and the configuration handlers ( classes ) that will handle the configuration information contained in the elements. When <configSections> is present, it must always be the first child element of <configuration> .

 <?xml version="1.0" encoding="UTF-8"?> <configuration> <configSections> .. </configSections> <!-- sections defined in configSections --> </configuration> 

Even if you are used to looking at a web.config file, you have probably never seen the <configSections> element. This is because all of the standard configuration handlers are defined in machine.config . (Recall that ASP.NET reads the machine.config file first and then the web.config file(s) for your application. All of the data from the machine.config file is used unless a section in web.config overrides the equivalent section in machine.config .) Because <configSections> is only used to define configuration handlers, it never appears in a web.config file, unless your application uses custom configuration handlers like the one described in this example.

In this example, we use a <siteProperties> custom element to hold the information we want to store in web.config and that will be used by our custom configuration handler. We have chosen the path of using a custom element (and a custom configuration handler) because of the flexibility it affords us and the clarity with which we can express the information to be stored.

In creating your own custom element, the first thing you need to do is determine the configuration information you want to store in web.config and then define the format that you want it stored in. The only limitation is that the data element itself must be a well-formed XML node. You can use attributes, child elements, or any combination of the two to hold your custom configuration information. In our example, we use attributes only. The well- formed XML that defines the section we want to add to our application web.config is shown here:

 <siteProperties applicationName="ASP.NET Cookbook" databaseServer="10.0.1.12" databaseName="ASPNetCookbook_DB" databaseUserName="aspnetcookbook" databaseUserPassword="efficient" emailServer="mail@mailservices.com" /> 

The section can be named anything you like as long as it does not conflict with any predefined ASP.NET elements. We recommend that, for consistency, you stick with the mixed-case convention used by ASP.NET. Also, be aware that section names and attributes are case sensitive.


After defining your configuration element and specifying the values of the information it will store, create a custom configuration handler in a separate project. This way the assembly that is created can be reused easily in multiple applications. For our example, the project was named VBCustomConfigHandlers ( CSCustomConfigHandlers for C#), which by default will generate an assembly with the same name .

In your configuration handler project, add a new class named to reflect the configuration element the handler supports. In our example, we've named the class VBSiteConfigHandler ( CSSiteConfigHandler for C#), because the section added to web.config contains site configuration information.

To act as a custom configuration handler, the class must implement the IConfigurationSectionHandler interface:

 
figs/vbicon.gif
 Namespace VBCustomConfigHandlers  Public Class VBSiteConfigHandler   Implements IConfigurationSectionHandler  .. End Class 'VBSiteConfigHandler End Namespace 'VBCustomConfigHandlers 
figs/csharpicon.gif
 namespace CSCustomConfigHandlers {  public class CSSiteConfigHandler : IConfigurationSectionHandler  { .. } // CSSiteConfigHandler } // CSCustomConfigHandlers 

The IConfigurationSectionHandler interface requires that you implement a single method, Create , which requires three parameters: parent , configContext , and section . The parent parameter provides a reference to the corresponding parent configuration section, and the configContext parameter provides a reference to the current ASP.NET context. Neither is used in this example. The section parameter provides a reference to the XML node (section) of the web.config file that is to be processed . In our example, section will be set to reference the <siteProperties> section added to web.config .

 
figs/vbicon.gif
 Namespace VBCustomConfigHandlers Public Class VBSiteConfigHandler Implements IConfigurationSectionHandler  Public Function Create(ByVal parent As Object, _   ByVal configContext As Object, _   ByVal section As XmlNode) As Object _   Implements IConfigurationSectionHandler.Create   ..   End Function 'Create  End Class 'VBSiteConfigHandler End Namespace 'VBCustomConfigHandlers 
figs/csharpicon.gif
 namespace CSCustomConfigHandlers { public class CSSiteConfigHandler : IConfigurationSectionHandler {  public Object Create(Object parent,   Object configContext,   XmlNode section)   {   ..   } // Create  } // CSSiteConfigHandler } // CSCustomConfigHandlers 

The Create method returns an object that contains the configuration information from the passed section. This can be anything you want it to be. The most flexible approach is to define a class that will contain the data and provide easy access by your application. In our example, the class that will be returned is defined in the same file as the VBSiteConfigHandler ( CSSiteConfigHandler for C#) class.

 
figs/vbicon.gif
 Namespace VBCustomConfigHandlers Public Class VBSiteConfigHandler Implements IConfigurationSectionHandler Public Function Create(ByVal parent As Object, _ ByVal configContext As Object, _ ByVal section As XmlNode) As Object _ Implements IConfigurationSectionHandler.Create .. End Function 'Create End Class 'VBSiteConfigHandler  'The following class provides the container returned by   'the VBSiteConfigHandler   Public Class VBSiteConfiguration   ..   End Class 'VBSiteConfiguration  End Namespace 'VBCustomConfigHandlers 
figs/csharpicon.gif
 namespace CSCustomConfigHandlers { public class CSSiteConfigHandler : IConfigurationSectionHandler { public Object Create(Object parent, Object configContext, XmlNode section) { .. } // Create } // CSSiteConfigHandler  // The following class provides the container returned by   // the CSSiteConfigHandler   public class CSSiteConfiguration   {   ..   } // CSSiteConfiguration  } // CSCustomConfigHandlers 

The VBSiteConfiguration ( CSSiteConfiguration for C#) class needs a constructor that has parameters for each of the configuration items and a read-only property for each of the configuration items. The code for our example is shown in Example 9-9 (VB) and Example 9-10 (C#).

After the class that will be used for the return is defined, the Create method should extract the configuration information from the passed XML section, create a new instance of the VBSiteConfiguration ( CSSiteConfiguration for C#) object, and then return a reference to the new instance. For our example, attributes were used for the configuration information in the section. This allows us to get a reference to the attributes collection of the section, and then extract the individual values by using the GetNameItem method of the attributes collection.

 
figs/vbicon.gif
 Public Function Create(ByVal parent As Object, _ ByVal configContext As Object, _ ByVal section As XmlNode) As Object _ Implements IConfigurationSectionHandler.Create Dim siteConfig As VBSiteConfiguration Dim attributes As XmlAttributeCollection  attributes = section.Attributes   With attributes   siteConfig = _   New VBSiteConfiguration(.GetNamedItem("applicationName").Value, _   .GetNamedItem("databaseServer").Value, _   .GetNamedItem("databaseName").Value, _   .GetNamedItem("databaseUserName").Value, _   .GetNamedItem("databaseUserPassword").Value, _   .GetNamedItem("emailServer").Value)   End With 'attributes   Return (siteConfig)  End Function 'Create 
figs/csharpicon.gif
 public Object Create(Object parent, Object configContext, XmlNode section) { CSSiteConfiguration siteConfig = null; XmlAttributeCollection attributes = null;  attributes = section.Attributes;   siteConfig =   new CSSiteConfiguration(attributes.GetNamedItem("applicationName").Value,   attributes.GetNamedItem("databaseServer").Value,   attributes.GetNamedItem("databaseName").Value,   attributes.GetNamedItem("databaseUserName").Value,   attributes.GetNamedItem("databaseUserPassword").Value,   attributes.GetNamedItem("emailServer").Value);   return (siteConfig);  } // Create 

With the custom configuration handler in hand, you then need to add the handler information to web.config to tell ASP.NET how to handle the <siteProperties> section you've added. Add a <configSections> element at the top of your web.config that contains a single section element. The name attribute defines the name of the custom section containing your configuration information. The type attribute defines the class and assembly name in the form type= " class , assembly " that will process your custom configuration section. The class name must be a fully qualified class name. The assembly name must be the name of the assembly ( dll ) created in your configuration handler project, described earlier.

 <configSections> <section name="siteProperties" type="VBCustomConfigHandlers.VBSiteConfigHandler, VBCustomConfigHandlers" /> </configSections> 

When the <configSections> element is present, it must always be the first element in the web.config file after the <configuration> element or a parsing exception will be thrown.


The last thing you need to do before you can use the custom configuration in your application is to add a reference to the VBCustomConfigHandlers ( CSCustomConfigHandlers for C#) assembly in your application.

Accessing the custom configuration information in your application requires using ConfigurationSettings.GetConfig and passing it the name of your custom section. This method returns an object that must be cast to the object type you returned in your custom configuration handler class. After the reference is obtained, all of the site information is available simply as properties of the object.

 
figs/vbicon.gif
 Dim siteConfig As VBCustomConfigHandlers.VBSiteConfiguration siteConfig = CType(ConfigurationSettings.GetConfig("siteProperties"), _ VBCustomConfigHandlers.VBSiteConfiguration) labApplicationName.Text = siteConfig.applicationName labDBServer.Text = siteConfig.databaseServer labDBName.Text = siteConfig.databaseName labDBUserName.Text = siteConfig.databaseUserName labDBUserPassword.Text = siteConfig.databaseUserPassword labEmailServer.Text = siteConfig.emailServer 
figs/csharpicon.gif
 CSCustomConfigHandlers.CSSiteConfiguration siteConfig = null; siteConfig = (CSCustomConfigHandlers.CSSiteConfiguration) (ConfigurationSettings.GetConfig("siteProperties")); labApplicationName.Text = siteConfig.applicationName; labDBServer.Text = siteConfig.databaseServer; labDBName.Text = siteConfig.databaseName; labDBUserName.Text = siteConfig.databaseUserName; labDBUserPassword.Text = siteConfig.databaseUserPassword; labEmailServer.Text = siteConfig.emailServer; 

Example 9-9. Custom section handler class (.vb)
 Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: VBSiteConfigHandler.vb ' ' Description: This class provides a custom site configuration handler. ' '***************************************************************************** Imports System.Configuration Imports System.Xml Namespace VBCustomConfigHandlers  Public Class VBSiteConfigHandler   Implements IConfigurationSectionHandler   '*************************************************************************   '   ' ROUTINE: Create   '   ' DESCRIPTION: This routine provides the creation of the   ' VBSiteConfiguration from the passed section of the   ' web.config file   '-------------------------------------------------------------------------   Public Function Create(ByVal parent As Object, _   ByVal configContext As Object, _   ByVal section As XmlNode) As Object _   Implements IConfigurationSectionHandler.Create   Dim siteConfig As VBSiteConfiguration   Dim attributes As XmlAttributeCollection   attributes = section.Attributes   With attributes   siteConfig = _   New VBSiteConfiguration(.GetNamedItem("applicationName").Value, _   .GetNamedItem("databaseServer").Value, _   .GetNamedItem("databaseName").Value, _   .GetNamedItem("databaseUserName").Value, _   .GetNamedItem("databaseUserPassword").Value, _   .GetNamedItem("emailServer").Value)   End With 'attributes   Return (siteConfig)   End Function 'Create   End Class 'VBSiteConfigHandler  'The following class provides the container returned by 'the VBSiteConfigHandler  Public Class VBSiteConfiguration   Private mApplicationName As String   Private mDatabaseServer As String   Private mDatabaseName As String   Private mDatabaseUserName As String   Private mDatabaseUserPassword As String   Private mEmailServer As String   Public ReadOnly Property applicationName( ) As String   Get   Return (mApplicationName)   End Get   End Property 'applicationName   Public ReadOnly Property databaseServer( ) As String   Get   Return (mDatabaseServer)   End Get   End Property 'databaseServer   Public ReadOnly Property databaseName( ) As String   Get   Return (mDatabaseName)   End Get   End Property 'databaseName   Public ReadOnly Property databaseUserName( ) As String   Get   Return (mDatabaseUserName)   End Get   End Property 'databaseUserName   Public ReadOnly Property databaseUserPassword( ) As String   Get   Return (mDatabaseUserPassword)   End Get   End Property 'databaseUserPassword   Public ReadOnly Property emailServer( ) As String   Get   Return (mEmailServer)   End Get   End Property 'emailServer   '*************************************************************************   '   ' ROUTINE: New   '   ' DESCRIPTION: This constructor creates the object and populates the   ' attributes with the passed values   '-------------------------------------------------------------------------   Public Sub New(ByVal applicationName As String, _   ByVal databaseServer As String, _   ByVal databaseName As String, _   ByVal databaseUserName As String, _   ByVal databaseUserPassword As String, _   ByVal emailServer As String)   mApplicationName = applicationName   mDatabaseServer = databaseServer   mDatabaseName = databaseName   mDatabaseUserName = databaseUserName   mDatabaseUserPassword = databaseUserPassword   mEmailServer = emailServer   End Sub 'New   End Class 'VBSiteConfiguration  End Namespace 'VBCustomConfigHandlers 

Example 9-10. Custom section handler class (.cs)
 //---------------------------------------------------------------------------- // // Module Name: CSCustomConfigHandlers // // Description: This class provides a custom site configuration handler. // //**************************************************************************** using System; using System.Configuration; using System.Xml; namespace CSCustomConfigHandlers {  public class CSSiteConfigHandler : IConfigurationSectionHandler   {   //************************************************************************   //   // ROUTINE: Create   //   // DESCRIPTION: This routine provides the creation of the   // CSSiteConfiguration from the passed section of the   // web.config file   //------------------------------------------------------------------------   public Object Create(Object parent,   Object configContext,   XmlNode section)   {   CSSiteConfiguration siteConfig = null;   XmlAttributeCollection attributes = null;   attributes = section.Attributes;   siteConfig =   new CSSiteConfiguration(attributes.GetNamedItem("applicationName").Value,   attributes.GetNamedItem("databaseServer").Value,   attributes.GetNamedItem("databaseName").Value,   attributes.GetNamedItem("databaseUserName").Value,   attributes.GetNamedItem("databaseUserPassword").Value,   attributes.GetNamedItem("emailServer").Value);   return (siteConfig);   } // Create   } // CSSiteConfigHandler  // The following class provides the container returned by // the CSSiteConfigHandler  public class CSSiteConfiguration   {   private String mApplicationName = null;   private String mDatabaseServer = null;   private String mDatabaseName = null;   private String mDatabaseUserName = null;   private String mDatabaseUserPassword = null;   private String mEmailServer = null;   public String applicationName   {   get   {   return(mApplicationName);   }   } // applicationName   public String databaseServer   {   get   {   return(mDatabaseServer);   }   } // databaseServer   public String databaseName   {   get   {   return(mDatabaseName);   }   } // databaseName   public String databaseUserName   {   get   {   return(mDatabaseUserName);   }   } // databaseUserName   public String databaseUserPassword   {   get   {   return(mDatabaseUserPassword);   }   } // databaseUserPassword   public String emailServer   {   get   {   return(mEmailServer);   }   } // emailServer   //************************************************************************   //   // ROUTINE: Constructor   //   // DESCRIPTION: This constructor creates the object and populates the   // attributes with the passed values   //------------------------------------------------------------------------   public CSSiteConfiguration(String applicationName,   String databaseServer,   String databaseName,   String databaseUserName,   String databaseUserPassword,   String emailServer)   {   mApplicationName = applicationName;   mDatabaseServer = databaseServer;   mDatabaseName = databaseName;   mDatabaseUserName = databaseUserName;   mDatabaseUserPassword = databaseUserPassword;   mEmailServer = emailServer;   } // CSSiteConfiguration   } // CSSiteConfiguration  } // CSCustomConfigHandlers 

Example 9-11. Changes to web.config to use the custom section handler
 <?xml version="1.0" encoding="utf-8"?> <configuration> ..  <configSections>   <section name="siteProperties"   type="VBCustomConfigHandlers.VBSiteConfigHandler, VBCustomConfigHandlers"   />   </configSections>  <system.web> .. </system.web> ..  <siteProperties applicationName="ASP.NET Cookbook"   databaseServer="10.0.1.12"   databaseName="ASPNetCookbook_DB"   databaseUserName="aspnetcookbook"   databaseUserPassword="efficient"   emailServer="mail@mailservices.com" />  </configuration> 

Example 9-12. Sample web form using custom configuration data (.aspx)
 <%@ Page Language="vb" AutoEventWireup="false" Codebehind="CH09CustomConfigHandlerVB.aspx.vb" Inherits="ASPNetCookbook.VBExamples.CH09CustomConfigHandlerVB"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Custom Config Handler</title> <link rel="stylesheet" href="css/ASPNetCookbook.css"> </head> <body leftmargin="0" marginheight="0" marginwidth="0" topmargin="0"> <form id="frmConfiguration" method="post" runat="server"> <table width="100%" cellpadding ="0" cellspacing="0" border="0"> <tr> <td align="center"> <img src="images/ASPNETCookbookHeading_blue.gif"> </td> </tr> <tr> <td class="dividerLine"> <img src="images/spacer.gif" height="6" border="0"></td> </tr> </table> <table width="90%" align="center" border="0"> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center" class="PageHeading"> Writing Custom Configuration Handlers (VB) </td> </tr> <tr> <td><img src="images/spacer.gif" height="10" border="0"></td> </tr> <tr> <td align="center"> <table width="60%"> <tr> <td align="right" width="50%" class="LabelText"> applicationName = </td> <td width="50%" class="LabelText"> <asp:Label ID="labApplicationName" runat="server" /> </td> </tr> <tr> <td align="right" class="LabelText"> databaseServer = </td> <td class="LabelText"> <asp:Label ID="labDBServer" runat="server" /> </td> </tr> <tr> <td align="right" class="LabelText"> databaseName = </td> <td class="LabelText"> <asp:Label ID="labDBName" runat="server" /> </td> </tr> <tr> <td align="right" class="LabelText"> databaseUserName = </td> <td class="LabelText"> <asp:Label ID="labDBUserName" runat="server" /> </td> </tr> <tr> <td align="right" class="LabelText"> databaseUserPassword = </td> <td class="LabelText"> <asp:Label ID="labDBUserPassword" runat="server" /> </td> </tr> <tr> <td align="right" class="LabelText"> emailServer = </td> <td class="LabelText"> <asp:Label ID="labEmailServer" runat ="server" /> </td> </tr> </table> </td> </tr> </table> </form> </body> </html> 

Example 9-13. Sample web form using custom configuration data code-behind (.vb)
 Option Explicit On Option Strict On '----------------------------------------------------------------------------- ' ' Module Name: CH09CustomConfigHandlerVB.aspx.vb ' ' Description: This module provides the code behind for the ' CH09CustomConfigHandlerVB.aspx page ' '***************************************************************************** Imports System.Configuration Namespace ASPNetCookbook.VBExamples Public Class CH09CustomConfigHandlerVB Inherits System.Web.UI.Page 'controls on the form Protected labApplicationName As System.Web.UI.WebControls.Label Protected labDBServer As System.Web.UI.WebControls.Label Protected labDBName As System.Web.UI.WebControls.Label Protected labDBUserName As System.Web.UI.WebControls.Label Protected labDBUserPassword As System.Web.UI.WebControls.Label Protected labEmailServer As System.Web.UI.WebControls.Label '************************************************************************* ' ' ROUTINE: Page_Load ' ' DESCRIPTION: This routine provides the event handler for the page load ' event. It is responsible for initializing the controls ' on the page. '------------------------------------------------------------------------- Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load  Dim siteConfig As VBCustomConfigHandlers.VBSiteConfiguration   siteConfig = CType(ConfigurationSettings.GetConfig("siteProperties"), _   VBCustomConfigHandlers.VBSiteConfiguration)   labApplicationName.Text = siteConfig.applicationName   labDBServer.Text = siteConfig.databaseServer   labDBName.Text = siteConfig.databaseName   labDBUserName.Text = siteConfig.databaseUserName   labDBUserPassword.Text = siteConfig.databaseUserPassword   labEmailServer.Text = siteConfig.emailServer  End Sub 'Page_Load End Class 'CH09CustomConfigHandlerVB End Namespace 

Example 9-14. Sample web form using custom configuration data code-behind (.cs)
 //---------------------------------------------------------------------------- // // Module Name: CH09CustomConfigHandlerCS.aspx.cs // // Description: This module provides the code behind for the // CH09CustomConfigHandlerCS.aspx page // //**************************************************************************** using System; using System.Configuration; namespace ASPNetCookbook.CSExamples { public class CH09CustomConfigHandlerCS : System.Web.UI.Page { // controls on the form protected System.Web.UI.WebControls.Label labApplicationName; protected System.Web.UI.WebControls.Label labDBServer; protected System.Web.UI.WebControls.Label labDBName; protected System.Web.UI.WebControls.Label labDBUserName; protected System.Web.UI.WebControls.Label labDBUserPassword; protected System.Web.UI.WebControls.Label labEmailServer; //************************************************************************ // // ROUTINE: Page_Load // // DESCRIPTION: This routine provides the event handler for the page // load event. It is responsible for initializing the // controls on the page. //------------------------------------------------------------------------ private void Page_Load(object sender, System.EventArgs e) {  CSCustomConfigHandlers.CSSiteConfiguration siteConfig = null;   siteConfig = (CSCustomConfigHandlers.CSSiteConfiguration)   (ConfigurationSettings.GetConfig("siteProperties"));   labApplicationName.Text = siteConfig.applicationName;   labDBServer.Text = siteConfig.databaseServer;   labDBName.Text = siteConfig.databaseName;   labDBUserName.Text = siteConfig.databaseUserName;   labDBUserPassword.Text = siteConfig.databaseUserPassword;   labEmailServer.Text = siteConfig.emailServer;  } //Page_Load } // CH09CustomConfigHandlerCS } 



ASP. NET Cookbook
ASP.Net 2.0 Cookbook (Cookbooks (OReilly))
ISBN: 0596100647
EAN: 2147483647
Year: 2006
Pages: 179

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net