views:

52

answers:

2

I have created a method that accepts an object then attempts to serialize the object to Xml by first using the XmlSerializer to serialize to a string, then load the Xml back into an XmlDocument object for the method to return. The code looks like this;

 public static XmlDocument ConvertObjectToXMLMessage(object ObjectToConvert)
    {
        MemoryStream stream = null;
        XmlWriter writer = null;
        XmlSerializer serializer = null;
        XmlDocument xmlDoc = new XmlDocument();
        UnicodeEncoding utf = new UnicodeEncoding();
        UTF8Encoding utf8 = new UTF8Encoding();
        ASCIIEncoding ascii = new ASCIIEncoding();
        string result = string.Empty;

        try
        {
            stream = new MemoryStream();
            //writer = new StreamWriter(stream, Encoding.Unicode);
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.UTF8;
            writer = XmlWriter.Create(stream, settings);                

            serializer = new XmlSerializer(ObjectToConvert.GetType());
            serializer.Serialize(writer, ObjectToConvert);

            int count = Convert.ToInt32(stream.Length);
            Byte[] arr = new Byte[count];

            stream.Seek(0, SeekOrigin.Begin);

            stream.Read(arr, 0, count);

            result = utf8.GetString(arr).Trim();

            // if this is being used during a debug session, the xml will be written to the Debug Console
#if DEBUG
            //blank line before
            Debug.WriteLine(string.Empty);
            // output result
            Debug.Write(result);
            //blank line after
            Debug.WriteLine(string.Empty);
#endif

            xmlDoc.LoadXml(result);

            return xmlDoc;
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (writer != null)
                writer.Close();
        }
    }

All works well until the xmlDoc.LoadXml(result) command. This throws an exception; {"Data at the root level is invalid. Line 1, position 1."}

As you can see, I have declared a number of encoding variables. If I use the ASCII encoding, it works. I need to use UTF8.

Any ideas why this does not work? I think it is because of spurious characters being inserted at the start of the Xml ofter serialisation. How do I avoid this? The types of classes that I could be serializing would be entity framework objects or proxy classed generated from XSD's or WSDL.

+1  A: 

What if you load the stream directly without manually reading it or converting it?

XmlDocument xd = new XmlDocument();
xd.Load( stream );

This will at least reduce the number of places an error could be occurring.

Tim
{"Root element is missing."}
Carl
@Carl what is the length of the stream? Just checking that it's not empty (because you would get the same error).
Tim
Tim, it is not empty. I thought that, but there is definitely content.
Carl
If I put the string from the variable result in to Notepad++ it shows a ? as the first char;
Carl
Then take a look at: http://stackoverflow.com/questions/1773654/utf8-beginning-of-file-characters-are-breaking-serializer-readers
Tim
Tim, that sorted it - thank you!!! Too many ways to use UTF8 encoding!
Carl
A: 

The code seems to be just fine... are you opening with an editor before trying to access your file by code?

I got that problem with an editor that was adding some stuff in my file

sebastian
I thought it was fine too! I cant open it with an editor first as it is all in memory.
Carl