views:

62

answers:

2

Hi guys,

I'm having what must be a VERY SILLY issue with the Data Contract Serializer. It refuses to work. I'm just trying to serialize an object into an XmlDocument, however I seem to be hitting a wall.

Here are the datacontracts I wish to serialise:

[DataContract(Namespace="urn://test", Name = "ServiceFault1")]
public class ServiceFault
{
    [DataMember()]
    public int hello { get; set; }

    [DataMember()]
    public List<Error> Errors {get; set;}
}

[DataContract(Namespace = "urn://test", Name = "Error1")]
public class Error
{
    [DataMember()]
    public string ErrorCategoryCode { get; set; }

    [DataMember()]
    public string LocalErrorCode { get; set; }

    [DataMember()]
    public string Description { get; set; }
}

And the method that does the serializing;

    public static XmlDocument Serialize(ServiceFault toSer)
    {
        DataContractSerializer ser = new DataContractSerializer(toSer.GetType());

        MemoryStream mem = new MemoryStream();
        ser.WriteObject(XmlWriter.Create(mem), toSer);

        XmlDocument tmp = new XmlDocument();
        mem.Seek(0, SeekOrigin.Begin);
        tmp.Load(mem);

        return tmp;
    }

Whenever I call the serialize method, the memory stream is always empty. I've tried a string builder as well, just to see if anything was coming out.

If I use the XmlSerailizer this works, however I'd like to understand why on earth the code above does not work? Why is the serializer always empty?

Thanks for any help! TM

+2  A: 

This is the code I use to serialize my objects and it seems to work for me. Also I think the DataContract attributes are not necessary, I'm only using an attribute in one place to ignore a member.

DataContractSerializer serializer = new DataContractSerializer(toSers.GetType());
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, toSer);
ms.Position = 0;

string serializedContent;
using(StreamReader sr = new StreamReader(ms))
{
  serializedContent = sr.ReadToEnd();   
}

The differences I see is that I'm writing directly to the MemoryStream, and setting the Position to 0, rather than calling Seek().

You could load the resulting string into an XmlDocument if you wanted to, using XmlDocument.LoadXml on the instance.

benr
A: 

The problem lies in the following line because the XmlWriter hasn't flushed it's contents to the memory stream yet:

ser.WriteObject(XmlWriter.Create(mem), toSer);

Try instead using:

public static XmlDocument Serialize(ServiceFault toSer)
{
    DataContractSerializer ser = new DataContractSerializer(toSer.GetType());
    XmlDocument tmp = new XmlDocument();
    using (MemoryStream mem = new MemoryStream())
    {
        using (var memWriter = XmlWriter.Create(mem))
        {
            ser.WriteObject(memWriter, toSer);
        }

        mem.Seek(0, SeekOrigin.Begin);
        tmp.Load(mem);
    }
    return tmp;
}
Reddog