• 第二十一章 数据访问(In .net4.5) 之 序列化


    1. 概述

      应用程序间传递数据,需要先将数据对象转化为字符流或字节流的形式,然后接收端收到后再转化回原始的数据对象。这就是序列化与反序列化。

      本章介绍 .net中的序列化与反序列化、序列化器的种类 以及 为序列化配置对象。

    2. 主要内容

      2.1 序列化与反序列化

        序列化只能保存对象的数据部分,不能保存方法部分。可以创建custom data transfer object(DTO)来只保存指定的数据信息。

        .net平台提供三种类型的序列化:

        ① XmlSerializer:

    [Serializable] 
    public class Person 
    { 
        public string FirstName { getset; } 
        public string LastName { getset; } 
        public int Age { getset; } 
    }
    XmlSerializer serializer new XmlSerializer(typeof(Person)); 
    string xml; 
    using (StringWriter stringWriter = new StringWriter()) 
    { 
        Person p new Person 
        { 
            FirstName = “John”, 
            LastName = “Doe”, 
            Age 42 
        }; 
        serializer.Serialize(stringWriter, p); 
        xml = stringWriter.ToString(); 
    } 
     
    Console.WriteLine(xml); 
     
    using (StringReader stringReader = new StringReader(xml)) 
    { 
        Person p = (Person)serializer.Deserialize(stringReader); 
        Console.WriteLine(“{0} {1is {2} years old”, p.FirstName, p.LastName, p.Age); 
    } 

          常用的几个attribute:   

          XmlIgnore
          XmlAttribute
          XmlElement
          XmlArray
            XmlArrayItem

    [Serializable] 
    public class Person 
    { 
        public string FirstName { getset; } 
        public string LastName { getset; } 
        public int Age { getset; } 
    }
    [Serializable] 
    public class Order 
    { 
        [XmlAttribute] 
        public int ID { getset; } 
     
        [XmlIgnore] 
        public bool IsDirty { getset; } 
     
        [XmlArray(“Lines”)] 
        [XmlArrayItem(“OrderLine”)] 
        public List<OrderLine> OrderLines { getset; } 
    } 
     
    [Serializable] 
    public class VIPOrder : Order 
    { 
        public string Description { getset; } 
    } 
     
    [Serializable] 
    public class OrderLine 
    { 
        [XmlAttribute] 
        public int ID { getset; } 
     
        [XmlAttribute] 
        public int Amount { getset; } 
     
        [XmlElement(“OrderedProduct”)] 
        public Product Product { getset; } 
    } 
     
    [Serializable] 
    public class Product 
    { 
        [XmlAttribute] 
        public int ID { getset; } 
        public decimal Price { getset; } 
        public string Description { getset; } 
    }
    private static Order CreateOrder() 
    { 
        Product p1 new Product { ID = 1, Description = “p2”, Price = 9 }; 
        Product p2 new Product { ID = 2, Description = “p3”, Price = 6 }; 
     
        Order order new VIPOrder 
        { 
            ID 4, 
            Description = “Order for John Doe. Use the nice giftwrap”, 
            OrderLines new List<OrderLine> 
            {  
                new OrderLine { ID = 5, Amount = 1, Product = p1}, 
                new OrderLine { ID = 6 ,Amount = 10, Product = p2}, 
            } 
        }; 
     
        return order; 
    }
    XmlSerializer serializer new XmlSerializer(typeof(Order),  
       new Type[] { typeof(VIPOrder) }); 
    string xml; 
    using (StringWriter stringWriter = new StringWriter()) 
    { 
        Order order = CreateOrder(); 
        serializer.Serialize(stringWriter, order); 
        xml = stringWriter.ToString(); 
    } 
    using (StringReader stringReader = new StringReader(xml)) 
    { 
        Order o = (Order)serializer.Deserialize(stringReader); 
        // Use the order 
    }

        ② binary serialization

    [Serializable] 
    public class Person 
    { 
        public int Id { getset; } 
        public string Name { getset; } 
        private bool isDirty = false; 
    } 
     
    Person p new Person 
    { 
        Id 1, 
        Name = “John Doe” 
    }; 
     
    IFormatter formatter new BinaryFormatter(); 
    using (Stream stream = new FileStream(“data.bin”, FileMode.Create)) 
    { 
        formatter.Serialize(stream, p); 
    } 
     
    using (Stream stream = new FileStream(“data.bin”, FileMode.Open)) 
    { 
        Person dp = (Person)formatter.Deserialize(stream); 
    }

          可以使用下列attributes来控制序列化与反序列化的过程

            OnDeserializedAttribute
            OnDeserializingAttribute
            OnSerializedAttribute
            OnSerializingAttribute

    [Serializable] 
    public class Person 
    { 
        public int Id { getset; } 
        public string Name { getset; } 
     
        [NonSerialized] 
        private bool isDirty = false; 
        [OnSerializing()] 
        internal void OnSerializingMethod(StreamingContext context) 
        { 
            Console.WriteLine(“OnSerializing.”); 
        } 
     
        [OnSerialized()] 
        internal void OnSerializedMethod(StreamingContext context) 
        { 
            Console.WriteLine(“OnSerialized.”); 
        } 
     
        [OnDeserializing()] 
        internal void OnDeserializingMethod(StreamingContext context) 
        { 
            Console.WriteLine(“OnDeserializing.”); 
        } 
     
        [OnDeserialized()] 
        internal void OnDeserializedMethod(StreamingContext context) 
        { 
            Console.WriteLine(“OnSerialized.”); 
        } 
    }

            通过实现ISerializable接口,可以进行更精细的序列化控制。

    [Serializable] 
    public class PersonComplex : ISerializable 
    { 
        public int Id { getset; } 
        public string Name { getset; } 
        private bool isDirty = false; 
     
        public PersonComplex() { } 
        protected PersonComplex(SerializationInfo info, StreamingContext context) 
        { 
            Id = info.GetInt32(“Value1”); 
            Name = info.GetString(“Value2”); 
            isDirty = info.GetBoolean(“Value3”); 
        } 
     
        [System.Security.Permissions.SecurityPermission(SecurityAction.Demand,  
                                                        SerializationFormatter true)] 
        public void GetObjectData(SerializationInfo info, StreamingContext context) 
        { 
            info.AddValue(“Value1”, Id); 
            info.AddValue(“Value2”, Name); 
            info.AddValue(“Value3”, isDirty); 
        } 
    }

        ③ 使用DataContract

          WCF中使用DataContract来将对象序列化为Xml或者Json格式。

    [DataContract] 
    public class PersonDataContract 
    { 
        [DataMember] 
        public int Id { getset; } 
         [DataMember] 
        public string Name { getset; } 
     
        private bool isDirty = false; 
    }

        ④ 使用Json序列化器

    [DataContract] 
    public class Person 
    { 
        [DataMember] 
        public int Id { getset; } 
        [DataMember] 
        public string Name { getset; } 
    } 
     
    Person p new Person 
    { 
        Id 1, 
        Name = “John Doe” 
    }; 
     
    using (MemoryStream stream = new MemoryStream()) 
    { 
        DataContractJsonSerializer ser new DataContractJsonSerializer(typeof(Person)); 
        ser.WriteObject(stream, p); 
     
        stream.Position 0; 
        StreamReader streamReader new StreamReader(stream); 
        Console.WriteLine(streamReader.ReadToEnd()); // Displays {“Id”:1,”Name”:”John Doe”} 
     
        stream.Position 0; 
        Person result = (Person)ser.ReadObject(stream); 
    }

    3. 总结

      ① 序列化 是将一个对象转化为一个字符流或者字节流的过程。反序列化正好相反。

      ② 可以使用XmlSerializer来实现Xml格式的序列化。还可以使用指定的attributes来配置序列化操作。

      ③ 可以使用BinaryFormatter来实现二进制格式的序列化。

      ④ Wcf中使用DataContractSerializer来配置序列化操作。

      ⑤ 使用DataContractJsonSerializer来创建轻型文本格式Json。

  • 相关阅读:
    第10组 Beta冲刺(2/4)
    第10组 Beta冲刺(1/4)
    第10组 Alpha冲刺(4/4)
    第08组 Beta版本演示
    第08组 Beta冲刺(4/4)
    第08组 Beta冲刺(3/4)
    第08组 Beta冲刺(2/4)
    第08组 Beta冲刺(1/4)
    第08组 Alpha事后诸葛亮
    第08组 Alpha冲刺(4/4)
  • 原文地址:https://www.cnblogs.com/stone_lv/p/4425636.html
Copyright © 2020-2023  润新知