在内部,根据文档,状态服务器用于BinaryFormatter
序列化复杂类型。 序列化标记为 的类或结构的BinaryFormatter
所有公共和私有字段[Serializable]
(不是属性!) 。但是XmlDocument
,正如您所指出的,没有如此标记,因此不能立即用BinaryFormatter
.
XmlDocument
但是,可以轻松地从字符串转换为字符串——文档表示的 XML 本身。因此,如果该XmlDocument
字段包含在实现的类型中ISerializable
,那么它GetObjectData()
可以简单地将相应的 XML 字符串存储在序列化流中。然后相应的序列化构造函数可以提取 XML 字符串并重构XmlDocument
.
由于ISerializable
在预先存在的类上实现可能很耗时,因此完成您想要的最简单的方法是为您的 XML 文档引入一个小型序列化包装器结构:
[Serializable]
public struct XmlDocumentSerializationWrapper : ISerializable
{
public static implicit operator XmlDocumentSerializationWrapper(XmlDocument data) { return new XmlDocumentSerializationWrapper(data); }
public static implicit operator XmlDocument(XmlDocumentSerializationWrapper wrapper) { return wrapper.XmlDocument; }
private readonly XmlDocument xmlDocument;
public XmlDocument XmlDocument { get { return xmlDocument; } }
public XmlDocumentSerializationWrapper(XmlDocument xmlDocument)
{
this.xmlDocument = xmlDocument;
}
public XmlDocumentSerializationWrapper(SerializationInfo info, StreamingContext context)
{
var xml = (string)info.GetValue("XmlDocument", typeof(string));
if (!string.IsNullOrEmpty(xml))
{
xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
}
else
{
xmlDocument = null;
}
}
#region ISerializable Members
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
if (XmlDocument != null)
{
var xml = XmlDocument.OuterXml;
info.AddValue("XmlDocument", xml);
}
else
{
info.AddValue("XmlDocument", (string)null);
}
}
#endregion
}
然后,在您要序列化的类中,将您的XmlDocument
字段(和自动实现的属性)替换为包装器结构字段,例如:
[Serializable]
public class TestClass
{
XmlDocumentSerializationWrapper doc;
public XmlDocument Document { get { return doc; } set { doc = value; } }
}
结构中的隐式运算符处理与包装器之间的自动转换。