zoukankan      html  css  js  c++  java
  • 继承自DynamicObject的对象的Xml序列化

    默认情况下,对继承自DynamicObject的对象进行序列化操作是不会报错的,但是并没有实际序列化出任何东西来

    为了让它进行序列化,我们改造一下实现类,实现IXmlSerializable接口

    代码
      /// <summary>
        
    /// 动态对象
        
    /// </summary>
        [Serializable]
        
    public class SkelectoneDynamicObject : DynamicObject, IXmlSerializable
        {

            
    #region 字段

            
    /// <summary>
            
    /// 集合字典,存放实际的对象
            
    /// </summary>
            private Dictionary<stringobject> dictionary = new Dictionary<stringobject>();

            
    #endregion

            
    #region 公有方法

            
    public override bool TryGetMember(GetMemberBinder binder, out object result)
            {
                
    string name = binder.Name.ToLower();
                
    bool exist = dictionary.TryGetValue(name, out result);
                
    if (!exist)
                {
                    
    // 不存在,默认空
                    result = null;
                }
                
    return true;
            }

            
    public override bool TrySetMember(SetMemberBinder binder, object value)
            {
                
    if (value == null)
                {
                    
    // 删除这个属性
                    Remove(binder.Name.ToLower());
                }
                
    else
                {
                    dictionary[binder.Name.ToLower()] 
    = value;
                }
                
    return true;
            }

            
    #endregion       
          
            
    #region IXmlSerializable 通过实现该接口,对DynamicObject进行XML序列化

            
    public System.Xml.Schema.XmlSchema GetSchema()
            {
                
    return null;
            }

            
    public void ReadXml(System.Xml.XmlReader reader)
            {
                XmlSerializer keySerializer 
    = new XmlSerializer(typeof(string));
                XmlSerializer typeSerializer 
    = new XmlSerializer(typeof(string));            
                
    if (reader.IsEmptyElement || !reader.Read())
                {
                    
    return;
                }

                
    while (reader.NodeType != XmlNodeType.EndElement)
                {
                    reader.ReadStartElement(
    "item"); 

                    reader.ReadStartElement(
    "key");
                    
    string key = (string)keySerializer.Deserialize(reader);
                    reader.ReadEndElement();

                    reader.ReadStartElement(
    "type");
                    
    string type = (string)typeSerializer.Deserialize(reader);
                    reader.ReadEndElement();

                    Type realType 
    = Type.GetType(type);

                    reader.ReadStartElement(
    "value");
                    XmlSerializer valueSerializer 
    = new XmlSerializer(realType);
                    
    object value = valueSerializer.Deserialize(reader);
                    reader.ReadEndElement();

                    reader.ReadEndElement();

                    dictionary.Add(key, value);
                    reader.MoveToContent();
                }
                reader.ReadEndElement();

            }

            
    public void WriteXml(System.Xml.XmlWriter writer)
            {
                XmlSerializer keySerializer 
    = new XmlSerializer(typeof(string));
                XmlSerializer typeSerializer 
    = new XmlSerializer(typeof(string));
                
    foreach (string key in dictionary.Keys)
                {
                    writer.WriteStartElement(
    "item");

                    writer.WriteStartElement(
    "key");
                    keySerializer.Serialize(writer, key);
                    writer.WriteEndElement();

                    writer.WriteStartElement(
    "type");
                    typeSerializer.Serialize(writer, dictionary[key].GetType().FullName);
                    writer.WriteEndElement();

                    writer.WriteStartElement(
    "value");
                    XmlSerializer valueSerializer 
    = new XmlSerializer(dictionary[key].GetType());
                    valueSerializer.Serialize(writer, dictionary[key]);
                    writer.WriteEndElement();

                    writer.WriteEndElement();
                }
            }

            
    #endregion
        }

    这样这个对象就可以xml序列化了,但是当它作为一个属性创建时,申明是dynamic的

    public dynamic ExtendedProperties = new SkelectoneDynamicObject();

    Xml序列化需要的是确定的类型,会报错

    Test method Goline.Test.GoblineCreatureTest.TestSave threw exception:
    System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type Skelectone.SkelectoneDynamicObject may not be used in this context. To use Skelectone.SkelectoneDynamicObject as a parameter, return type, or member of a class or struct, the parameter, return type, or member must be declared as type Skelectone.SkelectoneDynamicObject (it cannot be object). Objects of type Skelectone.SkelectoneDynamicObject may not be used in un-typed collections, such as ArrayLists.

    为此,我们构造一个用来序列化的对象

    代码
            /// <summary>
            
    /// 动态属性
            
    /// </summary>
            [XmlIgnore]
            
    public dynamic ExtendedProperties = new SkelectoneDynamicObject();

            
    /// <summary>
            
    /// 可序列化的动态属性
            
    /// 仅供系统内部使用,请不要使用该属性
            
    /// </summary>
            public SkelectoneDynamicObject SerializableExtendedProperties
            {
                
    get
                {
                    
    return ExtendedProperties;
                }
                
    set
                {
                    ExtendedProperties 
    = value;
                }
            }

    这样就实现了DynamicObject的Xml序列化,Binary序列化也可以类似实现ISerializable接口,这里就不给出实现了

  • 相关阅读:
    微信 token ticket jsapi_ticket access_token 获取 getAccessToken get_jsapi_ticket方法
    PHP 日志 记录 函数 支持 数组 对象 新浪 sae 环境 去掉 空格 换行 格式化 输出 数组转字符串
    原生 原始 PHP连接MySQL 代码 参考mysqli pdo
    PHP 数字金额转换成中文大写金额的函数 数字转中文
    使用PHPMailer发送带附件并支持HTML内容的邮件
    设置输出编码格式 header 重定向 执行时间 set_time_limit 错误 报告 级别 error_reporting
    html5 bootstrap pannel table 协议 公告 声明 文书 模板
    指向指针的指针
    二级指针
    c语言:当指针成为参数后
  • 原文地址:https://www.cnblogs.com/ueqtxu/p/1781559.html
Copyright © 2011-2022 走看看