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

相關問題