使用DataContractSerializer进行序列化,但无法反序列化回来

发布于 2024-10-17 11:21:58 字数 1226 浏览 7 评论 0原文

我有以下 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。

我做错了什么?我尝试重写反序列化函数几次,但似乎总是出现同样的错误。

哦,这就是我调用这两个函数的方式:

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

I have the following 2 functions:

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

The first one seems to serialize an object to an xml string just fine. The XML appears valid, no broken tags, no white spaces at the beginning or at the end, etc. Now the second function doesn't want to deserialize my XML string back to the object. On the last line I get:

There was an error deserializing the
object of type [MY OBJECT TYPE HERE].
The data at the root level is invalid.
Line 1, position 1.

What am I doing wrong? I tried rewriting the Deserialize function a few times, and it always seems to be the same kind of error.

Oh, and this is how I'm calling the 2 functions:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

对风讲故事 2024-10-24 11:21:59

我最终做了以下事情并且它有效。

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

看来主要问题是在调用stream.GetBuffer()时的Serialize函数中。调用stream.ToArray()似乎有效。

I ended up doing the following and it works.

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

It seems that the major problem was in the Serialize function when calling stream.GetBuffer(). Calling stream.ToArray() appears to work.

情释 2024-10-24 11:21:59

这是 Ray Vernagus 的稍微复杂的版本 序列化/反序列化方法。我使用的是 StringBuilder+XmlWriter 组合,而不是 MemoryStream+StreamReader,它允许控制缩进XML 输出的 (XmlWriterSettings.Indent< /code>):

public static string Serialize<T>(T value, bool indented = false)
{
    StringBuilder stringBuilder = new();
    XmlWriterSettings settings = new();
    settings.Indent = indented;
    DataContractSerializer serializer = new(typeof(T));
    using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, settings))
        serializer.WriteObject(xmlWriter, value);
    return stringBuilder.ToString();
}

public static T Deserialize<T>(string xml)
{
    ArgumentNullException.ThrowIfNull(xml);
    DataContractSerializer serializer = new(typeof(T));
    using StringReader stringReader = new(xml);
    using XmlReader xmlReader = XmlReader.Create(stringReader);
    return (T)serializer.ReadObject(xmlReader);
}

使用示例:

string xml = Serialize(obj, indented: true);

MyClass obj = Deserialize<MyClass>(xml);

警告:不要尝试通过转换 using 语句到 using 声明,因为在读取 StringBuilder 之前必须关闭 XmlWriter

Here is a slightly more sophisticated version of Ray Vernagus's Serialize/Deserialize methods. Instead of the MemoryStream+StreamReader I'm using the StringBuilder+XmlWriter combination, which allows to control the indentation of the XML output (XmlWriterSettings.Indent):

public static string Serialize<T>(T value, bool indented = false)
{
    StringBuilder stringBuilder = new();
    XmlWriterSettings settings = new();
    settings.Indent = indented;
    DataContractSerializer serializer = new(typeof(T));
    using (XmlWriter xmlWriter = XmlWriter.Create(stringBuilder, settings))
        serializer.WriteObject(xmlWriter, value);
    return stringBuilder.ToString();
}

public static T Deserialize<T>(string xml)
{
    ArgumentNullException.ThrowIfNull(xml);
    DataContractSerializer serializer = new(typeof(T));
    using StringReader stringReader = new(xml);
    using XmlReader xmlReader = XmlReader.Create(stringReader);
    return (T)serializer.ReadObject(xmlReader);
}

Usage example:

string xml = Serialize(obj, indented: true);

MyClass obj = Deserialize<MyClass>(xml);

Caution: Don't try to improve the using (XmlWriter line by converting the using statement to using declaration, because the XmlWriter has to be closed before reading the StringBuilder.

农村范ル 2024-10-24 11:21:59

这最适合 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);
        }

    }

This best for XML Deserialize

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

    }
百思不得你姐 2024-10-24 11:21:58

我一直都是这样做的:

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

Here is how I've always done it:

    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);
        }
    }
网名女生简单气质 2024-10-24 11:21:58

其他解决方案是:

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 会包含例如:

那么你当然不能使用其他示例中使用的 UTF8 编码..

Other solution is:

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

One remark: sometimes it happens that raw xml contains e.g.:

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

then of course you can't use UTF8 encoding used in other examples..

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文