DataContractSerializer.ReadObject is easily confused.

With WCF services you need to declare contracts and generate contract classes that encapsulate those contracts.  Most of the time you can simply let the framework deal with whatever it needs to do to deal with these objects.  Sometimes, you need to actually see without running a service what XML would result from a contract object or serialize a contract object from XML text.

In .NET 3.5 there exists the System.Runtime.Serialization.DataContractSerializer class that perform serialization of data contracts.

Based on its documentation it seems fairly simple to create data contract object to/from XML methods.  For example:

    public static T XmlToContractObject<T>(string xml) where T : class, IExtensibleDataObject

    {

        MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(xml));

        using (

        XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.Unicode,

                   new XmlDictionaryReaderQuotas(), null))

        {

            DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(T));

            return dataContractSerializer.ReadObject(reader) as T;

        }

    }

 

    public static string ContractObjectToXml<T>(T obj) where T : IExtensibleDataObject

    {

        DataContractSerializer dataContractSerializer = new DataContractSerializer(obj.GetType());

 

        String text;

        using (MemoryStream memoryStream = new MemoryStream())

        {

            dataContractSerializer.WriteObject(memoryStream, obj);

 

            text = Encoding.UTF8.GetString(memoryStream.GetBuffer());

        }

        return text;

    }

But, when you try to perform a round-trip from a contract object to XML and back you’ll notice that you get SerializationException with the cryptic message of "There was an error deserializing the object of type <sometype>.  The data at the root level is invalid", despite that the XML seems view when examined.

When Encoding.UTF8.GetString is called, it literally translates the entire array into a String object.  This means that it reads any and all 0 bytes in the array and dumps out null characters (”) into the string.  Why do I mention this?  Well, MemoryStream uses a self-expanding buffer to write to.  When MemoryStream runs out of space in its buffer, it doubles the size of the buffer, zeroes it out, then copies the original buffer to the start of the new buffer.  When MemoryStream.GetBuffer is called it simply gets a reference to this buffer, regardless of how many bytes have been written to the stream.  So, most of the time you get a buffer with zeroes padded to the end of it.

If you look closely at the resulting XML, there are a bunch of ” characters at the end of the string.

As it turns out, DataContractSerializer.ReadObject (or something it calls) doesn’t like all the extra null characters and this is the cause of the SerializationException.

Irritating as this may be, the fix is fairly straightforward.  Simply, create a new buffer equal to the length of the stream and copy the data from the MemoryStream buffer to the new one–trimming all the extra zeroes.  For example:

    public static string ContractObjectToXml<T>(T obj) where T : IExtensibleDataObject

    {

        DataContractSerializer dataContractSerializer = new DataContractSerializer(obj.GetType());

 

        String text;

        using (MemoryStream memoryStream = new MemoryStream())

        {

            dataContractSerializer.WriteObject(memoryStream, obj);

            byte[] data = new byte[memoryStream.Length];

            Array.Copy(memoryStream.GetBuffer(), data, data.Length);

 

            text = Encoding.UTF8.GetString(data);

        }

        return text;

    }

Digg ThisDotNetKick This

Working with Children

Every so often I work on a team with a member who cannot act professionally and is compelled to act childish.

For me, there’s different stages to dealing with people like this.  Ignoring the behaviour is the fist stage.  If they’re simply looking to get a rise out of your or are simply looking for attention, ignoring them sometimes makes the behaviour go away.

For people who are acting this way not to get attention or to get a rise, talking to them sometimes solves the problem.  Approaching them and simply saying “Your behaviour is not very professional.  It’s disturbing and counter-productive.  Could you please stop asking this way?”  This is usually enough to stop the people who simply don’t know their behaviour is unprofessional.

Now, occasionally, there’s people who are unable to work productive and professionally in a team and insist on acting unprofessionally.  At this point, depending on the organization, you have to get human resources involved.  In some organizations there’s a several stage process that needs to occur: verbal warnings, written warnings, dismissal.  In some organizations they’re just asked to pack-up and leave.

It’s unfortunate that situations like this arise and even more unfortunate when it escalates  to extreme measures.  If you’re encountered situations like this, how have you handled them?

Digg ThisDotNetKick This