Использование DataContractSerializer для сериализации, но не может десериализовать обратно
У меня есть следующие 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 ответа
Вот как я всегда это делал:
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);
}
}
Другое решение:
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, используемую в других примерах..
Я закончил тем, что сделал следующее, и это работает.
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() работает.
Это лучше всего для десериализации 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);
}
}