datacontract serialization and assertions

Billy McCafferty wrote a recent post on WCF and the problem with hidden serialization exceptions. This struck a cord with me as I realised that one thing that I always tend to leave out in my WCF scenarios is asserting that the type continues to remain serializable throughout iterative development.

I decided to take a look at how I might include this in my normal test first process and here's what I came up with:

public class when_serializing_my_object : 
    private static string propertyValue;
    private static MyObject returnedInstance;

    private context c = () => propertyValue = "aValue";

    public override MyObject create_sut()
        return new MyObject() { MyProperty = propertyValue };

    private because b = () => 
     returnedInstance = sut.DataContractSerializeAndDeserialize();

    public void should_serialize_through_wcf()

    public void should_have_correct_property_value()

public class MyObject
    public string MyProperty { get; set; }

I have a dummy class set up with one property and I am asserting that an instance is returned and that the correct property value is returned also.

The method I am using is a new extension method I created for this purpose:

public static class SerializeExtensions
    public static T DataContractSerializeAndDeserialize<T>(this T instance)
        var stream = new MemoryStream();
        var dataContractSerializer = new DataContractSerializer(typeof(T));

        dataContractSerializer.WriteObject(stream, instance);            

        stream.Position = 0;
        var newInstance = (T)dataContractSerializer.ReadObject(stream);


        return newInstance;

This uses the default WCF serialization class DataContractSerializer to serialize and then deserialize the instance of type T and is fairly straightforward.

When I run the tests I get a failure - this is correct because the MyObject class is decorated with the [DataContract] attribute but the MyProperty property is not decorated with [DataMember] at this time and including that attribute makes the test pass as I would expect.

What is unexpected is that taking the attributes off the class and property also causes the tests to pass... isn't DataContractSerialization supposed to be an opt-in only?.

Took me a while to find it, but it appears that in 3.5 SP1 there was a change so that by default any class without decorating attributes will be serialized by the DataContractSerializer So much for the opt-in part.

I'll be looking to include this in my next set of WCF classes and hoping it provides some pre-emptive support for hidden serialization issues - and thanks Billy!