0

У меня есть много классов, которые содержат поле и свойства типа XmlDocument. Когда я помещаю объекты этих классов в сеанс (например, State Server, SQL State Server), их необходимо сериализовать. Но если у нас есть свойство типа 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; } } 
} 

неявные операторы в структуру ручка автоматического преобразование F rom и к обертке.

+0

Танков много. он корректно работает для XmlDocument, а что же XslCompiledTransform? как я могу сериализовать этот класс? – Hadi

+1

@ Хэди - Я не так хорошо знаком с этим классом. Если вы можете найти способ извлечь XML-таблицу из класса в виде строки (или XmlDocument), вы можете использовать ту же технику. Предпочтительный формат для вопросов здесь: [один вопрос на вопрос] (http://meta.stackexchange.com/questions/222735/can-i-ask-only-one-question-per-post), поэтому я предлагаю просить второй вопрос. – dbc

 Смежные вопросы

  • Нет связанных вопросов^_^