简体   繁体   中英

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:

  • A leading ? character is added to the XML (which I've come to find out is a valid character, but we aren't handling apparently)
  • Child nodes aren't being included with some of the nodes.

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.

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);
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM