asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search





Active News
15 Seconds Weekly Newsletter
• Complete Coverage
• Site Updates
• Upcoming Features

More Free Newsletters
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

Creating a Flexible Configuration Section Handler
By Jeff Gonzalez
Rating: 3.8 out of 5
Rate this article


  • email this article to a colleague
  • suggest an article

    Introduction


    In this article I demonstrate how to create a flexible configuration section handler using C#. If you are a .NET developer, you have probably written a few configuration section handlers. I provide a summary background of the .NET configuration system, explain why the system is useful, and show how it can be extended.

    Configuration System Background and Concepts

    The premise for the .NET configuration system is simple -- to provide developers with a consistent manner for storing and reading configuration information. In the days before XML developers typically used initialization files (.ini), database, or a custom configuration format. Now a developer simply needs to implement the configuration interface and write his configuration handler accordingly.

    The .NET Configuration System provides several classes for programmatic access to the .NET Configuration settings. System.Configuration.ConfigurationSettings is the class for providing developer's access to their configuration files. This class has a very simple interface. The AppSettings property exposes the <AppSettings> configuration section so that developer's can retrieve settings based on the key/value pattern. This class also contains the method GetConfig(sectionName). This method provides a way for the developer to request the configuration settings for a specific section. Developers may also create custom configuration sections and handlers using the configuration framework. Configuration settings are created by a section handler that implements System.Configuration.IConfigurationSectionHandler. This interface exposes a method called Create. This method allows the developer to specifically handle the XML from the particular section they wish to convert into a settings object. This allows the developer to ignore details such as where the configuration file is located, parsing the configuration file for the particular section, and opening or closing the file. The Create method returns an object which can then be converted or cast into the correct settings object.

    Creating Configuration Section Handlers

    During development I often have the need to retrieve some values at runtime via the configuration system. My team recently developed several Web applications that utilized a single class for all pages to inherit from. In this class we handled authentication, authorization and page layout. We were able to use CSS to make our applications look very different, but maintain the same HTML code. In doing so we created a few objects related to stylesheets that allowed us to dynamically configure which stylesheets were included on a page. I will use this example as a way to demonstrate the different methods in which configuration handlers can be used.

    Overview of StyleSheet Scenario

    For our base page class, we wanted to be able to change which stylesheets should be included on the page via the configuration file. How we accomplished this was by creating a StyleSheet class, a StyleSheetCollection class and a StyleSheetSetting class. The StyleSheet class has 3 simple string properties named Name, Href, and Media. The StyleSheetCollection class inherited from CollectionBase and allows us to store multiple StyleSheet objects in a familiar fashion. The StyleSheetSetting class has one StyleSheetCollection property called StyleSheets.

    The StyleSheetSetting class is the object representation of the section found in the configuration section.

    Run of the Mill Section Handler

    Most developers (including myself before I saw the light) would write configuration section handlers for each specific configuration section. Once you learn the pattern of implementing the IConfigurationSectionHandler interface, creating handlers can become a tiring and boorish process. This section will demonstrate the basic method for creating configuration section handlers. In figure 1, the source code for my configuration file can be found. I have trimmed out the other configuration sections for brevity. In this configuration file you will notice I have created a section called StyleSheetSettings_1 and assigned the type BasicConfigurator to it. This tells the .NET configuration system to execute the BasicConfigurator.Create method whenever System.Configuration.ConfigurationSettings.GetConfig("StyleSheetSettings_1") is called.

    Figure 1

    <?xmlversion="1.0"encoding="utf-8"?>

    <configuration>

        <configSections>

            <sectionname="StyleSheetSettings_1"    
                type="FifteenSeconds.Core.BasicConfigurator, FifteenSeconds.Core"/>

     

        </configSections>

          

        <StyleSheetSettings_1>

            <StyleSheets>


                <Style SheetName="Page"Href="Styles/Page.css"Media="screen"/>

                <StyleSheetName="Custom"Href="Styles/Custom.css"Media="screen"/>
                <StyleSheetName="Print"Href="/Lib/Styles/Print.css"Media="print"/>

            </StyleSheets>     

        </StyleSheetSettings_1>

     </configuration>

    Inside the BasicConfiguration handler, we implement the Create method. Figure 2 contains the source code for this method. This method is how the .NET configuration system knows how to deal with the StyleSheetSettings_1 configuration section. We first create a StyleSheetSetting_1 object. This is the settings object that we will be returning. We then create an XmlNodeList and use an XPath query to select out all of the <StyleSheet> nodes from the section. We iterate through all of the nodes in this list and create a corresponding StyleSheet object. We assign the properties for this object based on the attributes found in the section XML. We then add the StyleSheet objects to the setting class' StyleSheetCollection StyleSheets property.

    There is nothing wrong with this method, and I am sure plenty of developers are comfortable doing this. This method does require a developer to create a new configuration section handler for every section or custom object model they create. In my next example I will show how to write a configuration section handler that can be reused no matter what type of object model is thrown at it.

    Figure 2

    public object Create(object parent, object configContext, System.Xml.XmlNode section)

    {

        StyleSheetSettings_1 settings = null;

     

        if (section == null) { return settings; }

     

        settings = new StyleSheetSettings_1();

     

        XmlNodeList styleSheets = section.SelectNodes(@"/StyleSheets/StyleSheet");

                                                   

        for (int i = 0; i < styleSheets.Count; i++)

        {

            XmlNode node = styleSheets.Item(i);

            StyleSheet styleSheet = new StyleSheet();

            styleSheet.Name = node.Attributes["Name"].InnerText;

            styleSheet.Href = node.Attributes["Href"].InnerText;

            styleSheet.Media = node.Attributes["Media"].InnerText;

     

            settings.StyleSheets.Add(styleSheet);

         }

     

         return settings;

    }

    XmlSerialzerConfiguration Section Handler

    During the process of developing our Web applications, we wrote several configuration section handlers. I was researching a way to abstract our handlers so that we could stop writing them for every section in our configuration files. I stumbled across Craig Andera's awesome article on using XmlSerialization to solve this problem. Thanks Craig! Figure 3 contains the code from the configuration file. Figure 4 contains the source code that Craig wrote.

    Figure 3

    <configuration>

        <configSections>

            <sectionname="StyleSheetSettings_1"    
                type="FifteenSeconds.Core.XmlConfigurator, FifteenSeconds.Core"/>

     

        </configSections>

     

        <StyleSheetSettings_1

    configuratorType="FifteenSeconds.Core.StyleSheetSettings_1, FifteenSeconds.Core">

           
            <StyleSheets>

                <StyleSheetName="Page"Href="/Lib/Styles/Page.css"Media="screen"/>

                <StyleSheetName="Custom"Href="/Lib/Styles/Custom.css"Media="screen"/>

                <StyleSheetName="Print"Href="/Lib/Styles/Print.css"Media="print"/>

            </StyleSheets>     

        </StyleSheetSettings_1>

    Figure 4

    public object Create(object parent, object configContext, System.Xml.XmlNode section)

    {

        Object settings = null;

     

        if (section == null) { return settings; }

     

        XPathNavigator navigator = section.CreateNavigator();

       
        String typeName = (string)navigator.Evaluate("string(@configuratorType)");

       
        Type sectionType = Type.GetType(typeName);

     

        XmlSerializer xs = new XmlSerializer(sectionType);

        XmlNodeReader reader = new XmlNodeReader(section);

     

        settings = xs.Deserialize(reader);

     

        return settings;

    }

    You will notice the code from the configuration file is very similar. The only difference lies in the section. An additional attribute was added called configuratorType. This allows the XmlConfigurator to determine at runtime the type of the setting object it should create. The XmlConfigurator.Create method contains the code for deserializing the XML into the correct setting object. We create an XPathNavigator from the section XmlNode. We use the Evaluate method off the navigator object to get the correct type name. Then we create a reference to the type using the Type.GetType static method. In the next step we create an XmlSerializer and pass the section's setting type in the constructor. The XmlNodeReader created from the section XML is then passed to the XmlSerializer.Deserialize method. This method returns an object corresponding to the settings object we are attempting to create. One thing Craig's code was missing, although he hinted at it in his article, was the ability to use the XML Serialization attributes to control the deserialization of the settings object. In Figure 5 the source code for the StyleSheet class is shown. For brevity I have only included 2 properties. To use the XML formatted with StyleSheet elements containing attributes corresponding to the StyleSheet class' properties, we had to decorate the public properties with some attributes.

    Figure 5

    [XmlAttribute(DataType="string", AttributeName="Name")]

    public string Name

    {

    get{return _Name;}

           set{_Name = value;}

    }

     

    [XmlAttribute()]

    public string Href

    {

           get{return _Href;}

           set{_Href = value;}

    }

    I have demonstrated in the code above, two different methods for decorating the properties. In the first example I explicitly assign the DataType and AttributeName properties in the attribute. Those properties can also be left off; XmlSerialization will assume the property with the same name and data type is what sholdbe serialized. I can see the explicit method being useful if you wish to serialize the property under a different name or data type.

    To prove my point of being able to reuse this configuration section handler no matter how an object model is structured, I have created a different set of classes. I created a DataConnection class with three string properties called Server, Database, and Security. I left the XmlAttribute off the public property statements, which requires you type each property out as an element in the configuration file. Figure 6 shows the configuration XML source. I also created a DataAccessSettings class with one DataConnection property called Connection.

    Figure 6

    <DataAccessSettingstype="FifteenSeconds.Core.DataAccessSettings, FifteenSeconds.Core">

        <Connection>

            <Server>(local);</Server>

            <Database>FifteenSeconds;</Database>

            <Security>Integrated Security=SSPI;</Security>

        </Connection>

    </DataAccessSettings>

    This will be turned into a settings object with a populated Connection property.

    Conclusion

    In this article I have demonstrated the usefulness of the .NET Configuration System. Utilizing the XmlSerialization capabilities of .NET we were able to accomplish significant reuse with our code. As Craig Andera puts it, I hope this is the last configuration section handler you ever write. I have included source in the form of a console application with a separate class library.

    About the Author

    Jeff Gonzalez has been involved in software development for over seven years. Jeff's diverse background has seen him working across North America in projects ranging from high volume commerce infrastructures to customer and employee management systems. Highly specialized in Microsoft solutions, Jeff has played key roles for leading companies like Microsoft, Rare Medium, Penson Financial, and city of Fort Worth. He is currently lending his talents to a company called Reynolds Web Solutions formerly Third Coast Media, developing custom software solutions for the automotive industry. He can be contacted at likwid@sumnurv.com.

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Other Articles
    Apr 21, 2005 - Building a FAQ Module for the ASP.NET Community Starter Kit
    This sample chapter from Packt Publishing's "Building Websites with the ASP.NET Community Starter Kit" illustrates how to build a new module on top of the existing code in the ASP.NET Community Starter Kit (CSK). Using a Frequently Asked Questions (FAQ) module as an example, it shows how creating a new module allows you to add entirely new features which integrate seamlessly with the rest of the framework.
    [Read This Article]  [Top]
    Oct 20, 2004 - Beyond the DataGrid: An Architectural View of the Data Source Model in ASP.NET 1.x and 2.0
    Dino Esposito discusses the differences between the DataGrid control in version 1.x and 2.0 of ASP.NET. In the process, he also builds an improved version of the 1.x control that can get you some of the new 2.0 features today.
    [Read This Article]  [Top]
    Aug 25, 2004 - Developing Web Parts with the ICellProvider Interface
    Most default SharePoint Server Web Parts can be connected across organizations. The second article in this series shows how to develop connectable Web Parts that provide information to other Web Parts.
    [Read This Article]  [Top]
    Aug 4, 2004 - Accessibility Improvements in ASP.NET 2.0 - Part 2
    Alex Homer continues to highlight some of the new ASP.NET 2.0 accessibility features. These features make it easier for visually impaired users to view and navigate Web sites and provide better support for alternative types of browsers and user agents.
    [Read This Article]  [Top]
    Jul 30, 2004 - Connectable Web Parts in SharePoint Portal Server 2003 - Part 1
    Most default SharePoint Server Web Parts can be connected across organizations. The first article in this series explains how to connect existing Web Parts using the connection Interface classes in the SharePoint architecture.
    [Read This Article]  [Top]
    Jul 27, 2004 - Accessibility Improvements in ASP.NET 2.0 - Part 1
    Alex Homer highlights some of the new ASP.NET 2.0 accessibility features. These features make it easier for visually impaired users to view and navigate Web sites and provide better support for alternative types of browsers and user agents.
    [Read This Article]  [Top]
    Jun 30, 2004 - Simplified and Extended Data Binding Syntax in ASP.NET 2.0
    Alex Homer discusses the simplification of, and extensions to, the ASP.NET 1.x data binding syntax, the new two-way data binding syntax for updating data sources, and the new syntax for binding to XML data in ASP.NET 2.0.
    [Read This Article]  [Top]
    May 18, 2004 - ASP.NET 2.0 Caching Features
    This article examines some of the new and exciting caching features in ASP.NET 2.0 and shows how to implement them in Web applications.
    [Read This Article]  [Top]
    May 11, 2004 - SharePoint Security and .NET Impersonation
    When implementing custom components that require access to restricted resources, implicit impersonation must be used. Jay Nathan shows how to create a class that makes using .NET Impersonation a snap.
    [Read This Article]  [Top]
    Apr 21, 2004 - Creating a Web Custom Control
    Conrad Jalali shows how to build Web custom controls by creating one that displays checkboxes in a categorized, hierarchical view.
    [Read This Article]  [Top]
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry