1. 概述

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

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

2. 主要内容

  2.1 序列化与反序列化

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

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

    ① XmlSerializer:

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

      常用的几个attribute:   

      XmlIgnore
      XmlAttribute
      XmlElement
      XmlArray
        XmlArrayItem

[Serializable]
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}
[Serializable]
public class Order
{
    [XmlAttribute]
    public int ID { get; set; }     [XmlIgnore]
    public bool IsDirty { get; set; }     [XmlArray(“Lines”)]
    [XmlArrayItem(“OrderLine”)]
    public List<OrderLine> OrderLines { get; set; }
} [Serializable]
public class VIPOrder : Order
{
    public string Description { get; set; }
} [Serializable]
public class OrderLine
{
    [XmlAttribute]
    public int ID { get; set; }     [XmlAttribute]
    public int Amount { get; set; }     [XmlElement(“OrderedProduct”)]
    public Product Product { get; set; }
} [Serializable]
public class Product
{
    [XmlAttribute]
    public int ID { get; set; }
    public decimal Price { get; set; }
    public string Description { get; set; }
}
private static Order CreateOrder()
{
    Product p1 = new Product { ID = , Description = “p2”, Price =  };
    Product p2 = new Product { ID = , Description = “p3”, Price =  };     Order order = new VIPOrder
    {
        ID = ,
        Description = “Order for John Doe. Use the nice giftwrap”,
        OrderLines = new List<OrderLine>
        { 
            new OrderLine { ID = , Amount = , Product = p1},
            new OrderLine { ID =  ,Amount = , 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 { get; set; }
    public string Name { get; set; }
    private bool isDirty = false;
} Person p = new Person
{
    Id = ,
    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 { get; set; }
    public string Name { get; set; }     [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 { get; set; }
    public string Name { get; set; }
    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 { get; set; }
    [DataMember]
    public string Name { get; set; }     private bool isDirty = false;
}

    ④ 使用Json序列化器

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

3. 总结

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

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

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

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

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

第二十一章 数据访问(In .net4.5) 之 序列化的更多相关文章

  1. 第二十二章 数据访问(In .net4.5) 之 集合

    1. 概述 本章内容包括 .net平台中的集合.如何选择集合 以及 如何实现自定义集合. 2. 主要内容 2.1 使用数组(Array) ]; ; x < arrayOfInt.Length;  ...

  2. 第十九章 数据访问(In .net4.5) 之 处理数据

    1. 概述 本章介绍 数据库.Json和Xml.web services 三种介质上的数据操作. 2. 主要内容 2.1 数据库 ① 建立连接 .net平台中的数据连接类都继承自DbConnectio ...

  3. JavaScript高级程序设计:第二十一章

    第二十一章 Ajax与Comet 一.XMLHttpRequest对象 1.XHT的用法 在使用XHR对象时,要调用的第一个方法时open( ),它接受3个参数:要发送的请求的类型.请求的URL和表示 ...

  4. 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(二) controller

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 开涛shiro教程-第二十一章-授予身份与切换身份(二) 1.回顾 ...

  5. 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(一) table、entity、service、dao

    原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第二十一章 授予身份与切换身份(一) 1.使用场景 某个领导因为某 ...

  6. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION)

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION) 学习目标 ...

  7. Flask 教程 第二十一章:用户通知

    本文翻译自The Flask Mega-Tutorial Part XXI: User Notifications 这是Flask Mega-Tutorial系列的第二十一章,我将添加一个私有消息功能 ...

  8. Gradle 1.12用户指南翻译——第二十一章. Gradle 插件

    昨天晚上只顾着和女朋友看<匆匆那年>电视剧的最后几集,所以说好的Android文档<Gradle 插件用户指南>第五章自然也没翻译多少.所以今天也发不了第五章的翻译了,就发几个 ...

  9. 第二十一章 Django的分页与cookie

    第二十一章 Django的分页与cookie 第一课 模板 1.模板的继承 在Template目录下新建模板master.html <!DOCTYPE html> <html lan ...

随机推荐

  1. Grid Infrastructure Single Client Access Name (SCAN) Explained (文档 ID 887522.1)

    APPLIES TO: Oracle Database - Enterprise Edition - Version 11.2.0.1 and laterExalogic Elastic Cloud ...

  2. 恶心的Oracle的if else if...

    出处:http://blog.sina.com.cn/s/blog_407d47e60100d8ig.html 前段时间写Oracle存储过程就遇到问题.原来写成这样if 1=2 then  null ...

  3. windows 服务的启动与安装

    在使用windows 操作系统时,我们对windows服务再也熟悉不过了,这些服务有的是系统层的,有的是应用层的,大部分都是运行在桌面的后台,可以在进程中看到,有时候在做web项目时,在站点启动时要启 ...

  4. phpDoc使用说明

    技术文档可以使人们更好得使用他人的代码库,然而,作为开发人员,编写文档确是一件让人头疼的事情.PHPDoc是PHP文档注释的一个标准,它可以实现为代码生成API文档. PHPDoc注释规范: 块注释的 ...

  5. ES6生成器基础

    ES6引进的最令人兴奋的特性就是一种新的函数生成方式,称为生成器(generator).名称有点奇怪,但是第一眼看上去行为更加奇怪.文章主要介绍生成器如何工作,然后让你明白为什么他们对于未来的JS会有 ...

  6. AX 的 NumberSequences

    EG: 在库存模块新加一个numberSequences. 1. 新加一个EDT\ SML_Test1; 2. 在库存模块的 class\NumberSeqReference_Inventory\Lo ...

  7. Loadrunner:安装LR11时提示缺少vc2005_sp1_with_atl_fix_redist

    [问题现象] 安装LR11时提示缺少vc2005_sp1_with_atl_fix_redist: [解决办法] 手动安装缺少的组件,LR安装包中已自带该组件,为何不自动捕捉异常去获取该自带的组件去安 ...

  8. Android IOS WebRTC 音视频开发总结(十八)-- 手机适配

    本文主要介绍上次碰到的某些机器上看不到视频的问题,文章来自博客园RTC.Blacker,转载请说明出处. 之前做的视频聊天App一直运行良好,前几天客户反馈说在三星9100. Android4.0.3 ...

  9. MySQL中的数据类型

    文本 CHAR(*):最多255个字节的定长字符串,它的长度必须在创建时指定 VARCHAR(*):最多255个字节的可变长度字符串,它的长度必须在创建时指定 TEXT:最大长度为64K字符的变长文本 ...

  10. JS创建对象的方式

    1.采用直接量创建方式:系统会使用new方式自动创建对象 var o = {x:1,y:2,z:2}; 2.采用new关键字创建对象:采用构造函数创建对象 var o = new Object();/ ...