Down the Rabbit Hole with C# Serialization

“Whooooo areeeee youuuuu?” No really, who are you and what are you doing on my blog? Oh you are here to read my blog entry on C# serialization to file writing? Fabulous! There may be times where you want to store an object’s data from C# to a file for reading later. You can essentially “freeze” the object in time and leave it in a file which later your program will read back in or be used by other programs. This is great for settings of a program (like configuration) and good for storing objects values in their current state. XML, the defacto standard these days for representing data and its structure, can be used with C# to record an object’s data and I will show you how to do it with a nice little example. So pull up a mushroom and chill for the Programming Underground is going to take you down the rabbit hole!

The program below is a small demo which will show you how to build a Novel of Alice in Wonderland. This is a console application in C# and is going to have three main attributes. First it is going to have the title, then we will specify the number of pages, and lastly the various chapters. Just to be different we are going to make the chapters a generic List of strings using some C# generics.

After we build the novel object we are going to then use the XMLSerializer object to serialize our object. We are also going to use a StreamWriter object to then write that serialized Novel to an XML file.

So lets dive in here and take a stare into the looking glass. By taking this blue pill you will see how far the rabbit hole goes! Oh wait, that part was from the Matrix. My mistake!

public class Novel
	{
		// Private member variables. Title, pages and a generic list of strings for chapters.
		private string bookTitle;
		private int numPages;
		private List<string> chapters = new List<string>();

		// Public properties which will be seen by XmlSerializer's serialize
		public string Title
		{
			get { return bookTitle; }
			set { bookTitle = value; }
		}

		public int Pages
		{
			get { return numPages; }
			set { if (value > 0) { numPages = value; } }
		}

		public List<string> Chapters
		{
			get { return chapters; }
		}

		// Little helper function for writing chapters to our object
		public void writeChapter(string chaptername)
		{
			chapters.Add(chaptername);
		}


		static void Main()
		{
			// So create our novel, give it a title and number of pages.
			Novel aNovel = new Novel();
			aNovel.Title = "Alice in Wonderland";
			aNovel.Pages = 105;

			// Use our function for writing chapters to the novel
			writeChapters(aNovel);

			// Ok, the novel is complete, so lets setup a serializer and a file stream
			XmlSerializer serializer = new XmlSerializer(aNovel.GetType());
			StreamWriter streamwrite = new StreamWriter("c:\\AliceInWonderland.xml");

			// Using the serializer, we call serialize and give it the stream and our novel
			// The novel is then serialized and put into the streamwrite stream.
			serializer.Serialize(streamwrite, aNovel);

			// Close the stream to end the process.
			streamwrite.Close();
		}

		// Function for writing our Alice in Wonderland chapters to the novel
		private static void writeChapters(Novel theNovel)
		{
			theNovel.writeChapter("Chapter 1: Down the Rabbit Hole");
			theNovel.writeChapter("Chapter 2: The Pool of Tears");
			theNovel.writeChapter("Chapter 3: A Caucus Race and a Long Tale");
			theNovel.writeChapter("Chapter 4: The Rabbit Sends in a Little Bill");
			theNovel.writeChapter("Chapter 5: Advice from a Caterpillar");
			theNovel.writeChapter("Chapter 6: Pig and Pepper");
			theNovel.writeChapter("Chapter 7: A Mad Tea Party");
			theNovel.writeChapter("Chapter 8: The Queen's Croquet Ground");
			theNovel.writeChapter("Chapter 9: The Mock Turtle's story");
			theNovel.writeChapter("Chapter 10: The Lobster Quadrille");
			theNovel.writeChapter("Chapter 11: Who Stole the Tarts?");
			theNovel.writeChapter("Chapter 12: Alice's Evidence");
		}
}

The first thing we do here is create an object called “Novel” and setup some private data members which will represent the Novel’s title, number of pages, and chapters. In order to get access to these variables we have created some public properties. These properties are going to be crucial for our serialization. The serialization process can only see the public features of our object so to get access to our object’s variables they would either have to be public (bad idea) or private with public accessors (better idea).

So we create a few properties to get access to our data and then we create a public method we can use for writing chapters to our chapters list. We give it a chapter name and then it will simply add on the chapter to the Novel’s chapters list. If you want to experiment with this code and expand it, you could look into chapter management functions here for numbering chapters automatically, sorting chapters, or edit/delete chapters. I will leave that up to you.

Then we have our main function where the program begins. Here we create an instance of our Novel object, set its title, number of pages and then we call a private helper method called “writeChapters” (notice the “s”) which we use to write Alice’s chapters to the novel (which we supply as a parameter). Make sense doesn’t it? We give our function a novel object and have it write a series of chapters by calling the novel’s writeChapter method. Simple.

After we write the chapters, the program returns to Main where we are ready to serialize this object. So lets make sure we include the System.Xml.Serialization and the System.IO namespaces to get access to the XMLSerializer object and the StreamWriter objects respectively.

Create a XMLSerializer object variable and as the constructor’s parameter we get the type of object it is using the “GetType()” method. This method is part of all objects since it is defined in “Object”. This is going to let the serializer know what type of object we are dealing with here and how to go about serializing it. In addition to this, we create a simple StreamWriter to write this object to an XML file we specify as a path in its constructor. Here we call it AliceInWonderland.xml and place it on the C:\ drive.

* Martyr2 takes a puff on the pipe and blows out the words “Almost done nowwwwww” just like the famous caterpillar.

The XMLSerializer object has a serialize() method which can take the stream we want to write to (here we use the StreamWriter stream we created) and then the Novel object we created. It uses what it knows of the object to then look at the public properties of our Novel, gets their values and then writes those values to the XML file stream. We end the whole process by closing the file stream.

The result is something along these lines….

<?xml version="1.0" encoding="utf-8"?>
<Novel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Title>Alice in Wonderland</Title>
  <Pages>105</Pages>
  <Chapters>
	<string>Chapter 1: Down the Rabbit Hole</string>
	<string>Chapter 2: The Pool of Tears</string>
	<string>Chapter 3: A Caucus Race and a Long Tale</string>
	<string>Chapter 4: The Rabbit Sends in a Little Bill</string>
	<string>Chapter 5: Advice from a Caterpillar</string>
	<string>Chapter 6: Pig and Pepper</string>
	<string>Chapter 7: A Mad Tea Party</string>
	<string>Chapter 8: The Queen's Croquet Ground</string>
	<string>Chapter 9: The Mock Turtle's story</string>
	<string>Chapter 10: The Lobster Quadrille</string>
	<string>Chapter 11: Who Stole the Tarts?</string>
	<string>Chapter 12: Alice's Evidence</string>
  </Chapters>
</Novel>

Pretty nifty huh? As you can see the object’s data (not its methods) have been preserved and placed in a XML structured file. We could then use C# later to call deserialize() which will read in this file we created and construct a Novel based on the data. In between these operations you could use programs to modify the data, publish the data to a website or whatever.

So just read through the code and read the in-code comments to see how the process works. This program is very easy to extend and grow into new programs that have a whole wide range of attributes. As with everything it is in the public domain and you can freely use it at your discretion.

Oh great, here comes tweedle dee and tweedle dumber, this caterpillar is outta here! Thanks for reading! 🙂

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebooks "The Programmers Idea Book" and "Diagnosing the Problem" . He has been a programmer for over 25 years. He works for a hot application development company in Vancouver Canada which service some of the biggest tech companies in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.