在进行C# XML序列化时,我遇到了一些陷阱,我认为我应该分享这些陷阱:
不能序列化只读的项(就像KeyValuePairs)
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序列化的问题?
发布于 2008-09-18 21:52:51
另一个巨大的陷阱是:当通过网页(ASP.NET)输出XML时,您不希望包含Unicode Byte-Order Mark。当然,使用或不使用BOM的方法几乎是相同的:
错误(包括BOM):
XmlTextWriter wr = new XmlTextWriter(stream, new System.Text.Encoding.UTF8);
好:
XmlTextWriter wr = new XmlTextWriter(stream, new System.Text.UTF8Encoding(false))
您可以显式地传递false来表明您不需要BOM。请注意Encoding.UTF8
和UTF8Encoding
之间的明显区别。
开头的三个额外的BOM字节是(0xEFBBBF)或(239 187 191)。
参考:http://chrislaco.com/blog/troubleshooting-common-problems-with-the-xmlserializer/
发布于 2008-09-16 00:25:17
我还不能发表评论,所以我会评论Dr8k的帖子,并做另一个观察。作为公共getter/setter属性公开的私有变量,并通过这些属性进行序列化/反序列化。我们一直在我以前的工作中这样做。
但是需要注意的一件事是,如果在这些属性中有任何逻辑,那么逻辑就会运行,所以有时序列化的顺序实际上很重要。成员是按照它们在代码中的排序方式进行隐式排序的,但没有保证,特别是当您继承另一个对象时。明确地对它们进行排序是一种后顾之忧。
在过去,我已经被这件事灼伤过。
发布于 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
https://stackoverflow.com/questions/67959
复制相似问题