使用XmlDocument属性序列化对象 [英] serialize object with XmlDocument Property

查看:179
本文介绍了使用XmlDocument属性序列化对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须拥有许多包含某些字段和类型为XmlDocument的属性的类. 当我将这些类的对象放入会话(例如状态服务器,SQL状态服务器)时,有必要对其进行序列化. 但是,如果我们具有XmlDocument类型的属性,并在类上方添加[Serialize] Attribute,则会出现以下错误.

I have to many classes that contains some field and properties of type XmlDocument. When I put the objects of these classes in session (such as state Server, SQL State Server) it is necessary to serialize them. But if we have a property of type XmlDocument and add [Serialize] Attribute above our class, the following error will be appears .

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

Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode.

对于具有[NonSerialize]属性的字段,不会出现此错误.这些属性不能具有属性[NonSerialize],因为它只能用于类和结构以及事件和委托.

this error does not appears for the fields have [NonSerialize] attribute. the properties can’t have the attribute [NonSerialize] because it can be used only for class and struct and event and delegate.

推荐答案

在内部,根据 [Serializable] .但是 XmlDocument 并没有如此标记,因此不能立即用BinaryFormatter序列化.

Internally, according to the docs, the state server uses BinaryFormatter to serialize complex types. BinaryFormatter serializes all public and private fields (not properties!) of a class or struct that is marked as [Serializable]. But XmlDocument, as you have noted, is not so marked, thus cannot be immediately serialized with BinaryFormatter.

XmlDocument可以简单地从字符串转换为字符串-文档表示的XML本身.因此,如果XmlDocument字段包含在实现 GetObjectData() 可以简单地将相应的XML字符串存储在序列化流中.然后,相应的序列化构造函数可以提取XML字符串并重新构成XmlDocument.

XmlDocument can, however, be trivially converted from and to a string -- the XML itself that the document represents. Thus if the XmlDocument field were contained in a type implementing ISerializable, then its GetObjectData() could simply store the corresponding XML string inside the serialization stream. Then the corresponding serialization constructor could extract the XML string and reconstitute the XmlDocument.

由于在预先存在的类上实现ISerializable可能很耗时,因此,完成所需操作的最简单方法是为XML文档引入一个小的序列化包装器结构:

Since implementing ISerializable on a pre-existing class can be time consuming, the easiest way to accomplish what you want would be to introduce a small serialization wrapper struct for your XML documents:

[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字段(和自动实现的属性)替换为包装结构字段,例如:

Then, in the classes you want to serialize, replace your XmlDocument fields (and auto-implemented properties) with wrapper struct fields, e.g.:

[Serializable]
public class TestClass
{
    XmlDocumentSerializationWrapper doc;

    public XmlDocument Document { get { return doc; } set { doc = value; } }
}

struct中的隐式运算符处理包装器之间的自动转换.

The implicit operators in the struct handle automatic conversion from and to the wrapper.

这篇关于使用XmlDocument属性序列化对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆