DataContractSerializer

使用提供的数据协定,将类型实例序列化和反序列化为 XML 流或文档。 无法继承此类。

命名空间: System.Runtime.Serialization
程序集:  System.Runtime.Serialization(在 System.Runtime.Serialization.dll 中)

备注

使用 DataContractSerializer 类可以将类型实例序列化和反序列化为 XML 流或文档。 通过将 DataContractAttribute 特性应用于类,而将DataMemberAttribute 特性应用于类成员,可以指定要序列化的属性和字段。

从字面意思来理解就是:数据契约序列化,本文主要是讲解用DataContractSerializer 序列化和反序列化,关于它在WCF中的应用大家可以参考《WCF全面解析上册 蒋金楠著》第五章 序列化,里面有专门的介绍。

DataContractAttribute与DataMenmberAttribute

 1 #region 程序集 System.Runtime.Serialization.dll, v4.0.0.0
 2 // C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Runtime.Serialization.dll
 3 #endregion
 4
 5 using System;
 6
 7 namespace System.Runtime.Serialization
 8 {
 9     // 摘要:
10     //     指定该类型要定义或实现一个数据协定,并可由序列化程序(如 System.Runtime.Serialization.DataContractSerializer)进行序列化。
11     //     若要使其类型可序列化,类型作者必须为其类型定义数据协定。
12     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum, Inherited = false, AllowMultiple = false)]
13     public sealed class DataContractAttribute : Attribute
14     {
15         // 摘要:
16         //     初始化 System.Runtime.Serialization.DataContractAttribute 类的新实例。
17         public DataContractAttribute();
18
19         // 摘要:
20         //     获取或设置一个值,该值指示是否保留对象引用数据。
21         //
22         // 返回结果:
23         //     如果使用标准 XML 保留对象引用数据,则为 true;否则为 false。 默认值为 false。
24         public bool IsReference { get; set; }
25         //
26         // 摘要:
27         //     获取或设置类型的数据协定的名称。
28         //
29         // 返回结果:
30         //     数据协定的本地名称。 默认值是应用了该属性的类的名称。
31         public string Name { get; set; }
32         //
33         // 摘要:
34         //     获取或设置类型的数据协定的命名空间。
35         //
36         // 返回结果:
37         //     协定的命名空间。
38         public string Namespace { get; set; }
39     }
40 }

DataContractAttribute

从应用在DataContractAttribute上的AttributeUsageAttribute特性看,该特性只能用于枚举、类、结构体而不能应用于接口,从关键字sealed知道DataContractAttribute是不可被继承的。AllowMutiple属性为False,表明一个数据类型上只能应用一个DataContractAttribute特性。

从上面对DataContractAttribute定义看出DataContractAttribute仅仅包含3个属性成员,其中Name和Namespace表示数据契约的名称和命名空间,IsReference表示在进行序列化的时候是否保持对象现有的引用结构,该属性默认值为False。

数据契约成员采用显示选择机制,也就是说,应用了DataContractAttribute特性的数据类型的属性/字段不会自动生成契约的数据成员,而只有那些应用了DataMemberAttribute特性的属性/字段才属于数据契约的成员。

 1 #region 程序集 System.Runtime.Serialization.dll, v4.0.0.0
 2 // C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Runtime.Serialization.dll
 3 #endregion
 4
 5 using System;
 6
 7 namespace System.Runtime.Serialization
 8 {
 9     // 摘要:
10     //     当应用于类型的成员时,指定该成员是数据协定的一部分并可由 System.Runtime.Serialization.DataContractSerializer
11     //     进行序列化。
12     [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
13     public sealed class DataMemberAttribute : Attribute
14     {
15         // 摘要:
16         //     初始化 System.Runtime.Serialization.DataMemberAttribute 类的新实例。
17         public DataMemberAttribute();
18
19         // 摘要:
20         //     获取或设置一个值,该值指定是否对正在被序列化的字段或属性的默认值进行序列化。
21         //
22         // 返回结果:
23         //     如果应该在序列化流中生成成员的默认值,则为 true;否则为 false。 默认值为 true。
24         public bool EmitDefaultValue { get; set; }
25         //
26         // 摘要:
27         //     获取或设置一个值,该值用于指示序列化引擎在读取或反序列化时成员必须存在。
28         //
29         // 返回结果:
30         //     如果该成员是必需的,则为 true;否则为 false。
31         //
32         // 异常:
33         //   System.Runtime.Serialization.SerializationException:
34         //     该成员不存在。
35         public bool IsRequired { get; set; }
36         //
37         // 摘要:
38         //     获取或设置数据成员名称。
39         //
40         // 返回结果:
41         //     该数据成员的名称。 默认值是应用该属性的目标的名称。
42         public string Name { get; set; }
43         //
44         // 摘要:
45         //     获取或设置成员的序列化和反序列化的顺序。
46         //
47         // 返回结果:
48         //     序列化或反序列化的数字顺序。
49         public int Order { get; set; }
50     }
51 }

DataMemberAttribute

从上面应用在DataMemberAttribute上的AttributeUsageAttribute特性来看,该特性只能应用在字段和属性上。因为只有这两种元素才是“数据”成员。4个属性分别表示如下的含义。

  • Name:数据成员的名称,默认为字段或属性的名称。
  • Order:相应的数据成员在最终序列化的XML中出现的位置,Order值越小越考前,默认值为-1.
  • IsRequired:表明属性成员是否是必须的成员。默认值为false,表明该成员是可以缺省的。
  • EmitDefaultValue :获取或设置一个值,该值指定是否对正在被序列化的字段或属性的默认值进行序列化。如果应该在序列化流中生成成员的默认值,则为 true;否则为 false。 默认值为 true。

 实例:

     Person类

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Runtime.Serialization;
 7 namespace DataContractSerializerDemo
 8 {
 9     [DataContract]
10     public class Person
11     {
12         public Person(string name, int age, DateTime bithday)
13         {
14             this.name = name;
15             this.age = age;
16             this.birthday = bithday;
17         }
18         private string name;
19         [DataMember]
20         public string Name
21         {
22             get { return name; }
23             set { name = value; }
24         }
25         private int age;
26         [DataMember]
27         public int Age
28         {
29             get { return age; }
30             set { age = value; }
31         }
32         private DateTime birthday;
33         [DataMember]
34         public DateTime Birthday
35         {
36             get { return birthday; }
37             set { birthday = value; }
38         }
39     }
40 }

Person

Women类(Person类的子类)

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Runtime.Serialization;
 7 namespace DataContractSerializerDemo
 8 {
 9     [DataContract]
10     public class Women : Person
11     {
12         public Women(string name, int age, DateTime birthday, string bwh, string bra)
13             : base(name, age, birthday)
14         {
15             BWH = bwh;
16             Bra = bra;
17         }
18         /// <summary>
19         /// 罩杯
20         /// </summary>
21         [DataMember]
22         public string BWH { get; set; }
23         /// <summary>
24         /// 罩颜色
25         /// </summary>
26         public string Bra { get; set; }
27     }
28 }

控制台程序:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Runtime.Serialization;
 7 using System.Xml;
 8 namespace DataContractSerializerDemo
 9 {
10     class Program
11     {
12         static void Main(string[] args)
13         {
14             Person p = new Person("wolfy", 24, Convert.ToDateTime("1989-04-11"));
15             Women w = new Women("苍老师",40,Convert.ToDateTime("1960-01-01"),"D罩杯","黑色蕾丝");
16             Serialize<Person>(p, "p.xml");
17             Serialize<Women>(w,"w.xml");
18             Console.Read();
19
20         }
21         /// <summary>
22         /// 序列化辅助方法
23         /// </summary>
24         /// <typeparam name="T"></typeparam>
25         /// <param name="instance"></param>
26         /// <param name="fileName"></param>
27         static void Serialize<T>(T instance, string fileName)
28         {
29             DataContractSerializer serializer = new DataContractSerializer(typeof(T));
30             using (XmlWriter writer = new XmlTextWriter(fileName,Encoding.UTF8))
31             {
32                 serializer.WriteObject(writer, instance);
33             }
34         }
35     }
36 }

最后生成的xml文件:p.xml

1 <Person xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/DataContractSerializerDemo"><Age>24</Age><Birthday>1989-04-11T00:00:00</Birthday><Name>wolfy</Name></Person>

w.xml

1 <Women xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/DataContractSerializerDemo"><Age>40</Age><Birthday>1960-01-01T00:00:00</Birthday><Name>苍老师</Name><BWH>D罩杯</BWH></Women>

将数据契约与最终生成的XML结构进行对比,我们可以看出DataContractSerializer在默认的情况下采用了如下的序列化规则。

  • XML的根节点名称为数据契约类型的名称(这里为Person),默认的命名空间采用的格式为 http://schemas.datacontract.org/2004/07/DataContractSerializerDemo(数据契约类型的命名空间)。
  • 只有显示地应用了DataMemberAttributue特性的字段或属性才能作为数据成员参与序列化。
  • 所有数据成员均以XML元素的形式被序列化。
  • 序列化后数据成员在XML中的次序采用这样的规则:父类数据成员在前,子类数据成员在后;定义在同一个类型中的数据成员按照字母排序。

如果默认序列化后的xml结构不能满足我们的需求,则可以通过DataContractAttribute和DataMenmberAttribute这两个特性对其进行修正。在下面我们通过DataContractAttribute特性设置了数据契约的名称和命名空间,通过DataMenmberAttribute特性的Name属性为Name和Birthday两个属性设置不同于属性名称的数据成员名称,并通过Order控制数据成员的先后次序。

修改后的Person类为:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Runtime.Serialization;
 7 namespace DataContractSerializerDemo
 8 {
 9     [DataContract(Namespace="http://www.wolfy.com/")]
10     public class Person
11     {
12         public Person(string name, int age, DateTime bithday)
13         {
14             this.name = name;
15             this.age = age;
16             this.birthday = bithday;
17         }
18         private string name;
19         [DataMember(Name="FirstName",Order=3)]
20         public string Name
21         {
22             get { return name; }
23             set { name = value; }
24         }
25         private int age;
26         [DataMember]
27         public int Age
28         {
29             get { return age; }
30             set { age = value; }
31         }
32         private DateTime birthday;
33         [DataMember(Name="生日",Order=1)]
34         public DateTime Birthday
35         {
36             get { return birthday; }
37             set { birthday = value; }
38         }
39     }
40 }

再次运行程序,得到如下一个表示序列化的Person对象的XML结构:

<Person xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.wolfy.com/"><Age>24</Age><生日>1989-04-11T00:00:00</生日><FirstName>wolfy</FirstName></Person>

有关序列化的方方面面还有很多,这里就把经常用到介绍到这里。

反序列化辅助方法:

 1  static T DeSerialize<T>(string fileName)
 2         {
 3             DataContractSerializer serializer = new DataContractSerializer(typeof(T));
 4             using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
 5             {
 6                 using (XmlReader reader = new XmlTextReader(fileName, fs))
 7                 {
 8                     return (T)serializer.ReadObject(reader);
 9                 }
10             }
11
12         }

运行结果为:

从反序列化的结果也从侧面印证了:只有显示地应用了DataMemberAttributue特性的字段或属性才能作为数据成员参与序列化。这条规则,因为在上面并没有给bra这个属性加DataMenmberAttribute这个特性,在生成的xml文件中没有这个元素。反序列化也不会出现这个。

上篇随笔: 序列化和反序列化的几种方式(JavaScriptSerializer 、XmlSerializer、DataContractSerializer)(一)

参考文献:

MSDN:http://msdn.microsoft.com/library/system.runtime.serialization.datacontractserializer.aspx

《WCF全面解析 上》 蒋金楠 著

转载于:https://www.cnblogs.com/wolf-sun/p/3319976.html

序列化和反序列化的几种方式(DataContractSerializer)(二)相关推荐

  1. Json 序列化以及反序列化的三种方式(二)

    1.什么是JSON? Json[javascript对象表示方法],它是一个轻量级的数据交换格式,我们可以很简单的来读取和写它,并且它很容易被计算机转化和生成,它是完全独立于语言的 2.Json支持下 ...

  2. 在C#中,Json的序列化和反序列化的几种方式总结

    在C#中,Json的序列化和反序列化的几种方式总结 在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 什么是JSON? JSON (Ja ...

  3. 序列化和反序列化的几种方式(JavaScriptSerializer 、XmlSerializer、DataContractSerializer)(一)...

    JavaScriptSerializer 类 为启用 AJAX 的应用程序提供序列化和反序列化功能. 命名空间:   System.Web.Script.Serialization 程序集:  Sys ...

  4. Json的序列化和反序列化的几种方式

    [什么是Json] 序列化:将对象转换成字节流的过程,这样就可以轻松将对象保存在磁盘文件或数据库中. 反序列化:序列化的逆过程,就是将字节流转换回原来的对象的过程. 当前主流的序列化JSON字符串主要 ...

  5. 二叉树序列化和反序列化的两种方式

    介绍 二叉树的序列化和反序列化,有两种方式: 第一种方式在将二叉树序列化为数组的时候,需要标记空指针为特殊符号,这样在反序列化的时候,就可以根据这些符号和序列方式来确定一颗二叉树. 第二种方式在序列化 ...

  6. Py之qrcode:调用python的qrcode库两种方式生成二维码、带logo的二维码

    Py之qrcode:调用python的qrcode库两种方式生成二维码.带logo的二维码 目录 python编程实现生成二维码 1.第一种方式-纯文本 2.第二种方式-带logo

  7. .NET 实现并行的几种方式(二)

    本随笔续接:.NET 实现并行的几种方式(一) 四.Task 3)Task.NET 4.5 中的简易方式 在上篇随笔中,两个Demo使用的是 .NET 4.0 中的方式,代码写起来略显麻烦,这不 .N ...

  8. Unity编辑器开发——通过模板创建Lua脚本的两种方式(二)

    个人学习笔记,如有错误.疑问.建议,欢迎留言. 本文有关代码转载自:Unity3D 扩展编辑器实现创建Lua脚本 - 知乎 (zhihu.com) 声明:本文转载已取得原文章作者同意,有兴趣的可以关注 ...

  9. .Net序列化与反序列化的2种方法

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

最新文章

  1. 深入解析Spring MVC与Web Flow
  2. 性能超过人类炼丹师,AutoGluon 低调开源
  3. mysql in 原理_深入理解MySql子查询IN的执行和优化
  4. 用c语言实现随机无向图的生成,C ++程序为给定数量的边生成随机无向图
  5. 使用ubuntu过程中遇到的问题汇总
  6. java多线程之hashmap concurrenthashmap的状态同步
  7. LeetCode Solutions : Reorder List
  8. vuejs项目如何修改node_mudule为公用文件?
  9. c语言生成随机英文字母,菜鸟求助,写一个随机输出26个英文字母的程序
  10. opencv中Mat与IplImage,CVMat类型之间转换
  11. 米斯特白帽培训讲义 工具篇 Nmap
  12. 电大有计算机教程吗,电大教程 计算机概述.ppt
  13. LINUX 安装护眼软件
  14. 1.Lunix系统安装及重置root密码
  15. 相量的瞬时功率 平均功率 无功功率 视在功率
  16. 抢先体验 Ubuntu 22.04 Jammy Jellyfish
  17. 连接到mysql提示错误:The server time zone value is unrecognized or represents more than one time zone
  18. Cocos Creator 新手引导制作
  19. gulp项目中的package配置说明
  20. 汇编语言中常用进制数据输出的程序实现

热门文章

  1. .net项目技术选型总结
  2. Java中final变量的初始化方式
  3. 625某电商网站数据库宕机故障解决实录(下)
  4. Android - Manifest 文件 详解
  5. JS三大对象中常用方法集锦
  6. 在MasterPage下FindControl的使用方法
  7. 我专严新闻小偷之心得与大家交流
  8. 20060911: 新机器·流氓软件
  9. 使IIS服务器支持下载 apk/ipa 安装包
  10. pdf转ppt怎么转换,pdf转换ppt的方法分享