Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Has anyone created a DataContract testing tool?

Has anyone seen a library that tests WCF DataContracts? The motivation behind asking this is that I just found a bug in my app that resulted from my not annotating a property with the DataMember attribute - as a result, that property wasn't being serialized.

What I have in mind is an API that, given a particular type of DataContract, will automatically populate its members with random data, including any child DataContracts, then serialize it via one of the WCF Serializers/Formatters and then check that all of the data has been carried across.

Anyone?

like image 994
Samuel Jack Avatar asked Jun 09 '09 15:06

Samuel Jack


People also ask

How to serialize DataContract in c#?

To create a type that conforms to the contract, first apply the DataContractAttribute to the class. Then apply the DataMemberAttribute to every field or property that you want to serialize. You can apply the DataMemberAttribute to both private and public members. The final format of the XML need not be text.

What is data contract?

A data contract is a formal agreement between a service and a client that abstractly describes the data to be exchanged. That is, to communicate, the client and the service do not have to share the same types, only the same data contracts.


1 Answers

It's simple enough to use DataContractSerializer to serialise your object to a MemoryStream, then deserialise it back into existence as a new instance.

Here's a class that demonstrates this round-trip serialisation:

public static class WcfTestHelper
{
    /// <summary>
    /// Uses a <see cref="DataContractSerializer"/> to serialise the object into
    /// memory, then deserialise it again and return the result.  This is useful
    /// in tests to validate that your object is serialisable, and that it
    /// serialises correctly.
    /// </summary>
    public static T DataContractSerializationRoundTrip<T>(T obj)
    {
        return DataContractSerializationRoundTrip(obj, null);
    }

    /// <summary>
    /// Uses a <see cref="DataContractSerializer"/> to serialise the object into
    /// memory, then deserialise it again and return the result.  This is useful
    /// in tests to validate that your object is serialisable, and that it
    /// serialises correctly.
    /// </summary>
    public static T DataContractSerializationRoundTrip<T>(T obj, 
                    IEnumerable<Type> knownTypes)
    {
        var serializer = new DataContractSerializer(obj.GetType(), knownTypes);
        var memoryStream = new MemoryStream();
        serializer.WriteObject(memoryStream, obj);
        memoryStream.Position = 0;
        obj = (T)serializer.ReadObject(memoryStream);
        return obj;
    }
}

Two tasks that you are responsible for:

  • Populating the instance in the first place with sensible data. You might choose to use reflection to set properties or supply a constructor with its arguments, but I've found this approach just won't work for anything other than incredibly simple types.
  • Comparing the two instances after you have round-trip de/serialised it. If you have a reliable Equals/GetHashCode implementation, then that might already be done for you. Again you might try using a generic reflective comparer, but this mightn't be completely reliable.
like image 121
Drew Noakes Avatar answered Sep 20 '22 06:09

Drew Noakes