Good judgement comes from experience, and experience comes from bad judgement. --Fred Brooks
Welcome to my blog and project site for Microsoft.NET development.

I've been a full time .NET developer for ten years, but I didn't start my professional life as a programmer ... more
Share/Print this page:

How Can I Easily Manage an XML Configuration File in .NET?

Using .NET's built-in XML serialization features

By steve on January 10, 2007.
Updated on January 22, 2012.
Viewed 39,247 times (0 times today).
Article TypesLanguage ElementsLanguagesSoftware DevelopmentTechnologiesTechnologies
SnippetIOC#Data.NETXML

Summary

Contents

XML serialization can be very easy in .NET. It is perfect for managing configuration files or small sets of data that don't need a full database solution.

The following code sample can be copied directly into a Visual Studio console project. Create the console project first. Then delete everything in the Class1.cs file replacing it with the code below. Compile and run.

So, the gist of it is this. Create a configuration class that will hold all of your configuration information. Then use .NET's built in XML Serialization features to read and write the XML configuration file.

One thing to watch out for when managing configuration files is versions. You will eventually realize that you wanted to store more variables in your configuration file or perhaps remove some that were there before.

For example, suppose your configuration class has a variable called Var1. Later on you realize you want to add a Var2, but there are already old config files out there that don't have a Var2. .NET will do a pretty good job of reading the XML file anyway and filling the properties it can find. In our example, there will be no value for Var2 in old XML files, so the Var2 property will be whatever it was initialized to.

But .NET may not be able to handle every situation you may face. You may find you need to do some customization, in that case it will be critical that you know the version number of the configuration file so that you can ensure it is parsed correctly. Anyway, versioning is a good practice. I learned the hard way, but you can benefit from my mistakes.

Simple Configuration File Using XML Serialization

Contents
using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace Cambia
{
   class MainClass
   {
   [STAThread]
      static void Main(string[] args)
      {
         // Create a new configuration object
         // and initialize some variables
         Configuration c = new Configuration();
         c.StringItem = "My Config";
         c.IntItem = 2456;

         // Serialize the configuration object to a file
         Configuration.Serialize("config.xml", c);

         // Read the configuration object from a file
         Configuration c2 = Configuration.Deserialize("config.xml");

         // Write out the variables read from the file
         Console.WriteLine(c2.StringItem);
         Console.WriteLine(c2.IntItem);

      }
   }

   #region -- Configuration Class --
   /// <summary>
   /// This Configuration class is basically just a set of 
   /// properties with a couple of static methods to manage
   /// the serialization to and deserialization from a
   /// simple XML file.
   /// </summary>
   [Serializable]
   public class Configuration
   {
      int _Version;
      string _StringItem;
      int _IntItem;

      public Configuration()
      {
         _Version = 1;
         _StringItem = "";
         _IntItem = -1;
      }
      public static void Serialize(string file, Configuration c)
      {
         System.Xml.Serialization.XmlSerializer xs 
            = new System.Xml.Serialization.XmlSerializer(c.GetType());
         StreamWriter writer = File.CreateText(file);
         xs.Serialize(writer, c);
         writer.Flush();
         writer.Close();
      }
      public static Configuration Deserialize(string file)
      {
         System.Xml.Serialization.XmlSerializer xs 
            = new System.Xml.Serialization.XmlSerializer(
               typeof(Configuration));
         StreamReader reader = File.OpenText(file);
         Configuration c = (Configuration)xs.Deserialize(reader);
         reader.Close();
         return c;
      }
      public int Version
      {
         get { return _Version; }
         set { _Version = value; }
      }
      public string StringItem
      {
         get { return _StringItem; }
         set { _StringItem = value; }
      }
      public int IntItem
      {
         get { return _IntItem; }
         set { _IntItem = value; }
      }

   }
   #endregion

}

Output from running the above console application

Contents
My Config
2456

Here's what the XML configuration file looks like

Contents
<Configuration>
   <Version>1</Version>
   <StringItem>My Config</StringItem>
   <IntItem>2456</IntItem>
</Configuration>
Back to Top

User Comments (10)

Posted 2007 Mar 08 16:10 PM. reply
Hi. This article was great. Really helped me a lot since this is my first time to do saving configuration to an XML file. Got a question though. What if I have an ArrayList item that I want save in the XML? How do I go about accomplishing this?

Thanks again.

Rick..
Reply 2007 Mar 08 22:15 PM by steve. reply
Hi Rick, I'm glad the article was helpful. When it comes to ArrayLists, if I recall, there are some complications. Regular arrays, however, work nicely. I have tended to add two properties to a class and add the [XmlIgnore] attribute to one of them like:

[XmlIgnore]
public ArrayList MyThingCollection
{
 get...
 set...
}
public MyThing[] MyThings
{
 get
 {
 return (MyThing[])_MyThingArrayList.ToArray(typeof(MyThing))
 }
 set
 {
 MyThingArrayList.Clear();
 MyThingArrayList.Add(value);
 }
}
Posted 2007 Aug 28 16:32 PM. reply
Thanks!

Googler1
Posted 2007 Oct 18 09:02 AM. reply
#region -- XML Class --
/// <summary>
/// This is a simple XML Serialization class;
/// </summary>
public class clsXML
{
public static void Serialize(string file, object o)
{
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(o.GetType());
StreamWriter writer = File.CreateText(file);
xs.Serialize(writer, o);
writer.Flush();
writer.Close();
}

public static object Deserialize(string file, object o)
{
System.Xml.Serialization.XmlSerializer xs = new System.Xml.Serialization.XmlSerializer(o.GetType());
StreamReader reader = File.OpenText(file);
o = xs.Deserialize(reader);
reader.Close();
return o;
}
}
#endregion

[Serializable]
public class Settings
{
public Settings()
{
boolSetting1 = false;
}

public bool Setting1
{
get
{
return boolSetting1;
}
set
{
boolSetting1 = value;
}
}
}

Lastly, in your code elsewhere:
Settings s;
s = (Settings)clsXML.Deserialize(strSettingsFile, (object)s);

clsXML.Serialize(strSettingsFile, (object)s);

^ This is a more generic implementation of your script, that allows for any seriazable object to be passed in or retrieve...Obviously there is no error checking to ensure the XML file is valid...

^ Anyway, the purpose of mine is I am going to have more than 1 settings file that deals with different areas of my app, and I don't have to have overload the Serialize/Deserialize functions for each different object type.

David
Reply 2007 Oct 18 21:12 PM by steve. reply
Nice. Thanks for the addition.
Replied 2010 Dec 17 01:54 AM by Rhino. reply
Why not just use an abstract base class XmlConfigFile with the serialization logic in the base, and derive from it for each of the various configuration files within the app to declare the data? It's more object-oriented as it doesn't avoid a real-world "is a" relationship. Furthermore, if it turns out down the road you do have a new unforseen config file which requires a different method of XML read/write other than simple XML serialization, then it can override the methods in the base class, yet still be treated as an "XML configuration file" black box. This also gives you an elegant way to deal with difficulty in versioning issues down the road by encapsulating the versioning logic in the derived class. Just some food for thought...
Posted 2009 Jul 07 11:10 AM. reply
Hi Steve,
thanks for your code. Currently I used XMLReader for loading the configuration. Your solution is much better!
My configuration class contains an array (int[]). Saving/Serialization works great, but loading from file not. How do I change the configuration class to get it working?

Thanks for your help.

Stefan
Replied 2009 Jul 08 05:14 AM by Stefan. reply
No change for arrays is required. The error was in my array declaration.

best regards
Posted 2010 Jun 04 11:37 AM. reply
Just suggestion next time not to name your class same way as System.Configuratin namespace classes..
You cannot use this for System.Configuration.Configuration class at all.

Petr
Reply 2010 Jun 07 14:39 PM by steve. reply
One would never use this for the built in configuration class. It has its own methods of serialization. This is for a custom configuration file. Also, note that the whole purpose of namespaces is to handle naming conflicts. My configuration object above is in the Cambia namespace and therefore has no conflict with the class in the .NET framework.
Post Your Comment
  You may post without logging in or login here.
Display Name: Required.
Email: Required. Will not be shown. Used for identicon.
Comment:
Allowed tags: <quote></quote>, <code></code>, <b></b>, <i></i>, <u></u>, <red></red>
 
   Please type text as shown in the image at left.