首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >.NET可扩展标记语言序列化问题?

.NET可扩展标记语言序列化问题?
EN

Stack Overflow用户
提问于 2008-09-15 23:35:15
回答 19查看 67.2K关注 0票数 121

在进行C# XML序列化时,我遇到了一些陷阱,我认为我应该分享这些陷阱:

不能序列化只读的项(就像KeyValuePairs)

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{      
    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        bool wasEmpty = reader.IsEmptyElement;
        reader.Read();

        if (wasEmpty)
            return;

        while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
        {
            reader.ReadStartElement("item");

            reader.ReadStartElement("key");
            TKey key = (TKey)keySerializer.Deserialize(reader);
            reader.ReadEndElement();

            reader.ReadStartElement("value");
            TValue value = (TValue)valueSerializer.Deserialize(reader);
            reader.ReadEndElement();

            this.Add(key, value);

            reader.ReadEndElement();
            reader.MoveToContent();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        foreach (TKey key in this.Keys)
        {
            writer.WriteStartElement("item");

            writer.WriteStartElement("key");
            keySerializer.Serialize(writer, key);
            writer.WriteEndElement();

            writer.WriteStartElement("value");
            TValue value = this[key];
            valueSerializer.Serialize(writer, value);
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
    }
}

还有没有其他XML序列化的问题?

EN

回答 19

Stack Overflow用户

发布于 2008-09-18 21:52:51

另一个巨大的陷阱是:当通过网页(ASP.NET)输出XML时,您不希望包含Unicode Byte-Order Mark。当然,使用或不使用BOM的方法几乎是相同的:

错误(包括BOM):

代码语言:javascript
复制
XmlTextWriter wr = new XmlTextWriter(stream, new System.Text.Encoding.UTF8);

好:

代码语言:javascript
复制
XmlTextWriter  wr = new XmlTextWriter(stream, new System.Text.UTF8Encoding(false))

您可以显式地传递false来表明您不需要BOM。请注意Encoding.UTF8UTF8Encoding之间的明显区别。

开头的三个额外的BOM字节是(0xEFBBBF)或(239 187 191)。

参考:http://chrislaco.com/blog/troubleshooting-common-problems-with-the-xmlserializer/

票数 27
EN

Stack Overflow用户

发布于 2008-09-16 00:25:17

我还不能发表评论,所以我会评论Dr8k的帖子,并做另一个观察。作为公共getter/setter属性公开的私有变量,并通过这些属性进行序列化/反序列化。我们一直在我以前的工作中这样做。

但是需要注意的一件事是,如果在这些属性中有任何逻辑,那么逻辑就会运行,所以有时序列化的顺序实际上很重要。成员是按照它们在代码中的排序方式进行隐式排序的,但没有保证,特别是当您继承另一个对象时。明确地对它们进行排序是一种后顾之忧。

在过去,我已经被这件事灼伤过。

票数 22
EN

Stack Overflow用户

发布于 2009-01-05 21:50:58

在从内存流序列化为XML时,请确保使用MemoryStream#ToArray()而不是MemoryStream#GetBuffer(),否则最终会得到不能正确反序列化的垃圾字符(因为分配了额外的缓冲区)。

http://msdn.microsoft.com/en-us/library/system.io.memorystream.getbuffer(VS.80).aspx

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67959

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档