2 minute read

I read Keith Ballinger’s excellent Web Services: Architecture and Implementation with .NET a few months ago, and it gave a fascinating approach to using XML Serialization. Keith suggests that this was really misnamed and that the term XML Mapping would be more appropriate because it is not designed to serialize any CLR object to XML, but rather designed to map any XML onto some set of CLR objects. Once you take this view and start to get a handle on the various XML mapping code attributes, XML serialization suddenly becomes much more powerful.

For this reason, many of the cases where I have used the DOM (XmlDocument) or XPathDocument in the past, can now be defined using a lot less code using XML Serialization. This also makes the code much more accessible for people with limited XML knowledge to use and extend in an intuitive manner. I’ve recently written a base class for dealing with custom configuration sections using this approach and thought I’d share it here.

There is an excellent article by Rockford Lhotka that explains what XML configuration files are and what they’re used for so I won’t repeat any of that here. In that article, Rockford demonstrates how to write the code for a custom configuration section by writing a class that implements the IConfigurationSectionHandler interface. If you want several config sections in your application, however, you end up writing a lot of code that is almost identical.

By using a base class for the configuration section handler, we can write a minimal amount of code describing simply what settings we want in our handler. Here is an example configuration settings class:

<font color="#0000FF">using</font> System;
<font color="#0000FF">using</font> System.Xml.Serialization;

[CustomConfigHandler("myConfig",Group="sampleConfig")]
<font color="#0000FF">public class</font> MyConfig : BaseConfigHandler
{
    [XmlAttribute("myString")]
    <font color="#0000FF">public string</font> MyString;

    [XmlAttribute("myInt")]
    <font color="#0000FF">public int</font> MyInt;

    <font color="#0000FF">public static</font> MyConfig Current {
        <font color="#0000FF">get</font> { <font color="#0000FF">return</font> (MyConfig)GetCurrent(<font color="#0000FF">typeof</font>(MyConfig)); }
    }
}

This class will parse a configuration section that looks like this:

<sampleConfig>
    <myConfig myString="abc" myInt="123" />
</sampleConfig>

The key points to take from this are that we use an attribute on the class CustomConfigHandler to indicate the name of the XML node (myConfig) and the group name (sampleConfig) and then we use standard XML Serialization attributes for the fields. This gives us strongly typed access to our settings. To access a setting in code, we simply refer to the Current property: MyConfig.Current.MyString.

Finally, we need to indicate in the .config file, where the code resides to process the custom handler. We do this by including a pointer to the handler code at the top of the .config file:

<configSections>
    <sectionGroup name="sampleConfig">
        <section name="myConfig" type="MyConfig,ConfigTest" />
    </sectionGroup>
</configSections>

This indicates that the class is called MyConfig in the assembly ConfigTest.

The code for the BaseConfigHandler is here and you can download a sample project to try out the code.

Updated: