0

我必须包含一些类型为XmlDocument的字段和属性的许多类。 当我将这些类的对象放入会话中时(例如状态服务器,SQL状态服务器),有必要序列化它们。 但是,如果我们有一个类型为XmlDocument的属性并在我们的类上面添加[Serialize]属性,则会出现以下错误。使用XmlDocument序列化对象属性

无法序列化会话状态。在“StateServer”和 “SQLServer”模式下,ASP.NET将序列化会话状态对象 ,结果不允许不可序列化的对象或MarshalByRef对象为 。如果类似序列化 由自定义会话状态存储以“自定义”模式完成,则适用相同的限制。

此错误不会显示为字段有[NonSerialize]属性。该属性不能具有属性[NonSerialize],因为它只能用于类和结构以及事件和委托。

回答

1

在内部,根据docs,状态服务器使用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; } } 
} 

在struct手柄自动转换f显示隐含的运营商ROM和包装。

+0

坦克很多。它适用于XmlDocument,那么XslCompiledTransform呢?我如何序列化这个类? – Hadi

+1

@哈迪 - 我对那个班不熟悉。如果您可以找出一种方法将XML样式表作为字符串(或XmlDocument)从类中提取出来,则可以使用相同的技术。这里问题的首选格式是[每个问题一个问题](http://meta.stackexchange.com/questions/222735/can-i-ask-only-one-question-per-post),所以我建议问一个问题第二个问题。 – dbc

相关问题