Coding Horror

programming and human factors

The Last Configuration Section Handler.. Revisited

If you need to store a little bit of state-- in your configuration file, or on disk-- nothing is faster than some quick and dirty serialization. Or as I like to call it, stringization.

In late 2004, I wrote about The Last Configuration Section Handler, which does exactly this for *.config files. It's based on earlier work by Craig Andera of Pluralsight. Let's bring that code up to date for Visual Studio 2005, and furthermore, we'll do it in C# and The Language of the Gods, VB.NET.

The first thing to do is set up a little class that represents the data you want to serialize. Include whatever types you need, but make everything public so it'll be visible to the serializer.

namespace SomeNamespace
{
    
public class MyStuff
    {
        
public int i;
        
public string s;
    }
}

Now use this routine to serialize it:

static string SerializeObject(object o)
{
    
StringBuilder sb = new StringBuilder();
    
StringWriter sw = new StringWriter(sb);
    
XmlTextWriter xtw = new XmlTextWriter(sw);
    
xtw.Formatting = Formatting.Indented;
    
xtw.WriteRaw(null);

    
XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
    
xsn.Add("", "");

    
XmlSerializer xs = new XmlSerializer(o.GetType());
    
xs.Serialize(xtw, o, xsn);
    
string s = sb.ToString();

    
// <Foo> becomes <Foo type="MyClass.Foo">
    s = Regex.Replace(s, "(<" + o.GetType().Name + ")(>)", "$1 type="" + o.GetType().FullName + ""$2");
    
return s;
}

The output is your class, serialized as a nice human-readable string.

<MyStuff type="SomeNamespace.MyStuff">
  <
i>1234</i>
  <
s>A bunch of information</s>
</
MyStuff>

It's just so darn.. straightforward. As if I needed another reason to love strings. Anyway, take that string and paste it into your web.config file.

To read it in, you'll need a custom config section. Paste this into your config file to define one:

<configSections>
  <
section name="MyStuff" type="XmlSerializerSectionHandler, CSSerializerSection" />
</
configSections>

The actual XmlSerializerSectionHandler is a bit too much code to paste into a blog post, but it's still relatively simple:

  1. Extract the type from the XML Type attribute
  2. Make sure the type is valid
  3. Deserialize the XML into a new object of that type

The XmlSerializerSectionHandler is too verbose to reprint here mainly because I added a bunch of error trapping. If something goes wrong, you get a nice explanatory exception instead of a cryptic error. It's good stuff.

There's almost no difference at all between the two languages, except that VB for some reason requires an additional namespace; instead of "SomeNamespace.MyStuff", it's "VBSerializerSection.SomeNamespace.MyStuff".

Written by Jeff Atwood

Indoor enthusiast. Co-founder of Stack Exchange and Discourse. Disclaimer: I have no idea what I'm talking about. Find me here: http://twitter.com/codinghorror