第二十一章 数据访问(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。

原文地址:https://www.cnblogs.com/stone_lv/p/4425636.html