Использование DataContractSerializer для сериализации, но не может десериализовать обратно - PullRequest
62 голосов
/ 16 февраля 2011

У меня есть следующие 2 функции:

public static string Serialize(object obj)
{
    DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
    MemoryStream memoryStream = new MemoryStream();
    serializer.WriteObject(memoryStream, obj);
    return Encoding.UTF8.GetString(memoryStream.GetBuffer());
}

public static object Deserialize(string xml, Type toType)
{
    MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
   // memoryStream.Position = 0L;
    XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8, new XmlDictionaryReaderQuotas(), null);
    DataContractSerializer dataContractSerializer = new DataContractSerializer(toType);
    return dataContractSerializer.ReadObject(reader);
}

Первый, кажется, отлично сериализует объект в строку XML. XML выглядит корректным, без битых тегов, без пробелов в начале или в конце и т. Д. Теперь вторая функция не хочет десериализовать мою строку XML обратно в объект. На последней строке я получаю:

Произошла ошибка при десериализации объект типа [МОЙ ОБЪЕКТ ТИПА ЗДЕСЬ]. Данные на корневом уровне неверны. Строка 1, позиция 1.

Что я делаю не так? Я несколько раз пытался переписать функцию десериализации, и всегда кажется, что это одна и та же ошибка. Спасибо!

О, и вот как я вызываю 2 функции:

SomeObject so = new SomeObject();
string temp = SerializationManager.Serialize(so);
so = (SomeObject)SerializationManager.Deserialize(temp, typeof(SomeObject));

Ответы [ 4 ]

134 голосов
/ 16 февраля 2011

Вот как я всегда это делал:

    public static string Serialize(object obj) {
        using(MemoryStream memoryStream = new MemoryStream())
        using(StreamReader reader = new StreamReader(memoryStream)) {
            DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
            serializer.WriteObject(memoryStream, obj);
            memoryStream.Position = 0;
            return reader.ReadToEnd();
        }
    }

    public static object Deserialize(string xml, Type toType) {
        using(Stream stream = new MemoryStream()) {
            byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
            stream.Write(data, 0, data.Length);
            stream.Position = 0;
            DataContractSerializer deserializer = new DataContractSerializer(toType);
            return deserializer.ReadObject(stream);
        }
    }
34 голосов
/ 02 января 2012

Другое решение:

public static T Deserialize<T>(string rawXml)
{
    using (XmlReader reader = XmlReader.Create(new StringReader(rawXml)))
    {
        DataContractSerializer formatter0 = 
            new DataContractSerializer(typeof(T));
        return (T)formatter0.ReadObject(reader);
    }
}

Одно замечание: иногда случается, что сырой xml содержит, например:

<?xml version="1.0" encoding="utf-16"?>

тогда, конечно, вы не можете использовать кодировку UTF8, используемую в других примерах ..

33 голосов
/ 16 февраля 2011

Я закончил тем, что сделал следующее, и это работает.

public static string Serialize(object obj)
{
    using (MemoryStream memoryStream = new MemoryStream())
    {
        DataContractSerializer serializer = new DataContractSerializer(obj.GetType());
        serializer.WriteObject(memoryStream, obj);
        return Encoding.UTF8.GetString(memoryStream.ToArray());
    }
}

public static object Deserialize(string xml, Type toType)
{
    using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
    {
        XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8, new XmlDictionaryReaderQuotas(), null);
        DataContractSerializer serializer = new DataContractSerializer(toType);
        return serializer.ReadObject(reader);
    }
}

Кажется, что основная проблема была в функции Serialize при вызове stream.GetBuffer ().Вызов stream.ToArray () работает.

0 голосов
/ 09 августа 2011

Это лучше всего для десериализации XML

 public static object Deserialize(string xml, Type toType)
    {

        using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
        {
            System.IO.StreamReader str = new System.IO.StreamReader(memoryStream);
            System.Xml.Serialization.XmlSerializer xSerializer = new System.Xml.Serialization.XmlSerializer(toType);
            return xSerializer.Deserialize(str);
        }

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...