Goose
Goose

Reputation: 3279

XML Serialization changes in upgraded project (.NET 3.5 to 4.5)

Recently upgraded a 3.5 project to 4.5. There is a chunk of data that we are serializing and storing in the database, but everytime a save occurs in the upgraded project, the XML formatting has changed, throwing errors, and I can't seem to figure out the core issue. There are 2 SO questions in particular that mention encoding changes, but I've tried switching to UTF8 (in a few different ways specified in the answers on those questions), without any success - with UTF8 I just got a mess of strange characters throughout the entire file.

The main issues that I can see occurring are:

Here is our serialization method:

public static string SerializeXml<T>(T instance) 
{ 
    XmlSerializer serializer = new XmlSerializer(typeof(T));
    MemoryStream memStream = new MemoryStream();
    XmlTextWriter xmlWriter = new XmlTextWriter(memStream, Encoding.Unicode);
    serializer.Serialize(xmlWriter, instance);
    memStream = (MemoryStream)xmlWriter.BaseStream;

    return UnicodeEncoding.Unicode.GetString(memStream.ToArray()).Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "");
}

and our deserialization method:

public static T DeserializeXml<T>(string xml) 
{ 
    XmlSerializer xs = new XmlSerializer(typeof(T)); 
    StringReader reader = new StringReader(xml); 

    return (T)xs.Deserialize(reader); 
} 

Any help would be appreciated, I am not too familiar with serialization or encoding. Just curious what may have changed with the upgrade to 4.5, or if there is something I need to take a closer look at.

Upvotes: 1

Views: 224

Answers (1)

Mike Burdick
Mike Burdick

Reputation: 838

If you want to Serialize to a String you need to use UTF16. If you want to Serialize with UTF8 you need to serialize to a byte[]. Strings in C# are UTF16 so in the code you posted I believe all your data is encoded with UTF16 but because you are omitting the Xml Declaration code assumes it is UTF8.

I would recommend using functions like this and not omitting the XmlDeclaration:

    public static string SerializeXmlToString<T>(T instance)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));

        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Encoding = Encoding.Unicode;

        StringBuilder builder = new StringBuilder();

        using (StringWriter writer = new StringWriter(builder))
        using (XmlWriter xmlWriter = XmlWriter.Create(writer, settings))
        {
            serializer.Serialize(xmlWriter, instance);
        }

        return builder.ToString();
    }

    public static byte[] SerializeXml<T>(T instance)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));

        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Encoding = Encoding.UTF8;

        using (MemoryStream memStream = new MemoryStream())
        {
            using (XmlWriter xmlWriter = XmlWriter.Create(memStream, settings))
            {
                serializer.Serialize(xmlWriter, instance);
            }

            return memStream.ToArray();
        }
    }

    public static T DeserializeXml<T>(string data)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));

        using (StringReader reader = new StringReader(data))
        {
            return (T)serializer.Deserialize(reader);
        }
    }

    public static T DeserializeXml<T>(byte[] bytes)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));

        using(MemoryStream stream = new MemoryStream(bytes))
        {
            return (T)serializer.Deserialize(stream);
        }
    }

Upvotes: 1

Related Questions