Serializing Data with System.Runtime.Serialization.DataContractSerializer

Last time we discussed Serializing Data with System.Xml.Serialization.XmlSerializer. We will be using the same sample solution for this article.

With .Net 3.5, Microsoft released the DataContractSerializer. It has a variety of uses, but at the very least it’s an improvement over the XmlSerializer. In Cash Tracker we started out by using the XmlSerializer to save files, but quickly found it inadequate, the reason being XmlSerializer does not play well with mixed access properties.

For an example, let’s look again at our Person class:

public class Person {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Initials { get; private set; }

    private Person() {
    }
    public Person(string first, string last) {
        this.FirstName = first;
        this.LastName = last;

        this.Initials = String.Format("{0}.{1}.", FirstName[0], LastName[0]);
    }
}
Notice I’ve added a new property with a private mutator. Also, I added a constructor to take advantage of the new property and made my default constructor private. Now when we try to serialize using the XmlSerializer we get an error:

Unable to generate a temporary class (result=1).

error CS0200: Property or indexer ‘Person.Initials’ cannot be assigned to — it is read only

What to do?

In .Net 3.5, to get around this problem, Microsoft suggests using the DataContractSerializer, so we will investigate switching to the new technology here. First, we need a reference to System.Runtime.Serialization:

image

Once that’s done it’s actually pretty simply converting our old code. The new code looks like this:

static void XmlSerializePerson(Person myPerson, string fileName) {
    DataContractSerializer xs = new DataContractSerializer(typeof(Person));

    using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write)) {
        xs.WriteObject(fs, myPerson);
    }
}

static Person XmlDeserializePerson(string fileName) {
    DataContractSerializer xs = new DataContractSerializer(typeof(Person));

    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
        return (Person)xs.ReadObject(fs);
    }
}

Notice we simply re-used the old methods, changing the object and methods used to serialize our Person. Our code will now execute as expected:

image

Download the Solution

You can download a zip file of the solution by clicking the link below.

DataContractSerializerDemo.zip

Leave a Reply