Sunday, February 22, 2015

(De) serializing objects with private / protected properties using XmlSerializer, DataContractSerializer and Newtonsoft.JSON

So since I 'discovered' that objects with private / protected properties can be handled by Entity Framework, I needed to make sure they can also be serialized and deserialized properly. Because in my unit tests I do not want to test the database connection, I often make use of serialized objects that I use for testing.

However, not all libraries that handle serialization can work with private / protected properties. So here's a comparsion of:

  1. System.Xml.Serialization.XmlSerializer
  2. System.Runtime.Serialization.DataContractSerializer
  3. Newtonsoft.Json

In case you're curious: I'll be using Newtonsoft.Json from now on. 2 reasons: clean serialization format, and no modifications required on the class declaration.

System.Xml.Serialization.XmlSerializer
Cannot work with private properties. Will throw an InvalidOperationException during deserialization.

System.Runtime.Serialization.DataContractSerializer
Will deserialize an object properly, in case the class has the [Serializable] attribute. If this attribute is NOT present, the private / internal / protected / and protected internal properties are NOT serialized. So beware.

Downside: property serialization is verbose and very ugly:

<_x003c_id_x003e_k__backingfield>0
<_x003c_internalproperty_x003e_k__backingfield>Internal
<_x003c_name_x003e_k__backingfield>John Doe
<_x003c_privateproperty_x003e_k__backingfield>Private
<_x003c_protectedinternalproperty_x003e_k__backingfield>ProtectedInternal
<_x003c_protectedproperty_x003e_k__backingfield>Protected

But it will work.

Newtonsoft.JSON
Works out of the box with any access modifier. Also - the serialized format is very clean:
{
  "Id": 0,
  "Name": "John Doe",
  "ProtectedProperty": "Protected",
  "PrivateProperty": "Private",
  "InternalProperty": "Internal",
  "ProtectedInternalProperty": "ProtectedInternal"
}


NOTE: I did not do any type of performance benchmark, since I'm not really interested in it in the case of unit testing. Also - I did not look into serialization formats that are impossible to read ( binary or protocol-buffers )  since I want to be able to look at the data I'm using while testing.





No comments:

Post a Comment