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

JavaScriptSerializer 类

为启用 AJAX 的应用程序提供序列化和反序列化功能。

命名空间: System.Web.Script.Serialization

程序集: System.Web.Extensions(在 System.Web.Extensions.dll 中)

JavaScriptSerializer 类由异步通信层内部使用,用于序列化和反序列化在浏览器和 Web 服务器之间传递的数据。 您无法访问序列化程序的此实例。 但是,此类公开了公共 API。 因此,当您希望在托管代码中使用 JavaScript 对象符号 (JSON) 时可以使用此类。

若要序列化对象,请使用 Serialize 方法。 若要反序列化 JSON 字符串,请使用 DeserializeDeserializeObject 方法。 若要序列化和反序列化 JavaScriptSerializer 本身不支持的类型,请使用 JavaScriptConverter 类来实现自定义转换器。 然后,使用 RegisterConverters 方法注册转换器。

关于SerializeDeserialize的应用:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Web.Script.Serialization;
 7 namespace Wolfy.SerializerDemo
 8 {
 9     class Program
10     {
11         static void Main(string[] args)
12         {
13             List<Person> persons = new List<Person>{
14                                    new Person("wolfy",24,Convert.ToDateTime("1989-04-11")),
15                                    new Person("张三",23,Convert.ToDateTime("1990-04-11")),
16                                    new Person("李四",22,Convert.ToDateTime("1991-04-11")),
17                                    new Person("王五",21,Convert.ToDateTime("1992-04-11"))
18                                };
19             //创建JavaScriptSerializer对象
20             JavaScriptSerializer jss = new JavaScriptSerializer();
21             //调用序列化方法Serialize
22             string json = jss.Serialize(persons);
23             Console.WriteLine("序列化.....");
24             Console.WriteLine(json);
25             Console.WriteLine("反序列化.....");
26             JavaScriptSerializer jss2 = new JavaScriptSerializer();
27             List<Person> list = jss2.Deserialize<List<Person>>(json);
28             foreach (Person item in list)
29             {
30                 Console.WriteLine(item.Name + "\t" + item.Age.ToString() + "\t" + item.Birthday);
31             }
32
33             Console.Read();
34         }
35     }
36 }

Person类

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6
 7 namespace Wolfy.SerializerDemo
 8 {
 9     public class Person
10     {
11         public Person() { }
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
20         public string Name
21         {
22             get { return name; }
23             set { name = value; }
24         }
25         private int age;
26
27         public int Age
28         {
29             get { return age; }
30             set { age = value; }
31         }
32         private DateTime birthday;
33
34         public DateTime Birthday
35         {
36             get { return birthday; }
37             set { birthday = value; }
38         }
39     }
40 }

运行结果:

注意:Date 对象,在 JSON 中表示为“\/Date(刻度数)\/”。 刻度数是一个正的或负的长值,该值指示从 UTC 1970 年 1 月 1 日午夜开始已经过的刻度数(毫秒)。

所支持的最大日期值为 MaxValue(9999 年 12 月 31 日 11:59:59 PM),而所支持的最小日期值为 MinValue(0001 年 1 月 1 日 12:00:00 AM)。如果想得到如“2013-01-01”需要对时间进行转换:这里提供一种js转换的方式,具体方法如下:

简单的分页存储过程,Json格式日期转换为一般日期

在对Person序列化需注意:Person类要有无参的构造函数。不然在反序列化时会出现如下错误:

XmlSerializer类

将对象序列化到 XML 文档中和从 XML 文档中反序列化对象。XmlSerializer 使您得以控制如何将对象编码到 XML 中。

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

XML 序列化是将对象的公共属性 (Property) 和字段转换为序列格式(这里是指 XML)以便存储或传输的过程。反序列化则是从 XML 输出中重新创建原始状态的对象。因此,可以将序列化视为将对象的状态保存到流或缓冲区的方法。例如,ASP.NET 使用 XmlSerializer 类对 XML Web services 消息进行编码。

对象中的数据是用编程语言构造来描述的,如类、字段、属性 (Property)、基元类型、数组,甚至 XmlElementXmlAttribute 对象形式的嵌入 XML。您可以创建自己的用属性 (Attribute) 批注的类,或使用 XML 架构定义工具 (Xsd.exe) 生成基于现有 XML 架构定义 (XSD) 文档的类。如果有 XML 架构,则可以运行 XSD.exe 产生一组类,将这组类的类型强声明为此架构,并用属性 (Attribute) 批注这些类以便在序列化时遵循此架构。

在对象和 XML 之间传输数据需要从编程语言构造到 XML 架构的映射和从 XML 架构到编程语言构造的映射。XmlSerializer 和相关工具(如 Xsd.exe)在设计时和运行时都能在这两种技术之间提供一个桥梁。在设计时,使用 Xsd.exe 可从自定义类产生 XML 架构文档 (.xsd) 或从给定架构产生类。不论何种情况,这些类都用自定义属性 (Attribute) 批注,以指示 XmlSerializer 如何在 XML 架构系统和公共语言运行库之间映射。在运行时,可以将这些类的实例序列化到遵循给定架构的 XML 文档中。同样,可以将这些 XML 文档反序列化到运行时对象中。注意,XML 架构是可选的,在设计时或运行时不是必需的。

控制生成的 XML

为控制所生成的 XML,可以向类和成员应用特殊属性 (Attribute)。例如,为指定不同的 XML 元素名称,可以将 XmlElementAttribute 应用于公共字段或属性 (Property),同时设置 ElementName 属性 (Property)。有关类似属性的完整列表,请参见 控制 XML 序列化的属性。也可以实现 IXmlSerializable 接口以控制 XML 输出。

如果所生成的 XML 必须符合万维网联合会 (www.w3.org) 文档“简单对象访问协议 (SOAP) 1.1”的第 5 部分,则必须利用 XmlTypeMapping 构造 XmlSerializer。若要进一步控制编码后的 SOAP XML,请使用 控制编码的 SOAP 序列化的属性 中所列的属性 (Attribute)。

有了 XmlSerializer,可以利用使用强类型类的优点并仍具有 XML 的灵活性。通过在强类型类中使用类型为 XmlElementXmlAttributeXmlNode 的字段或属性 (Property),可以将部分 XML 文档直接读入 XML 对象中。

如果使用扩展 XML 架构,则也可以使用 XmlAnyElementAttributeXmlAnyAttributeAttribute 属性 (Attribute) 来序列化及反序列化在原始架构中找不到的元素或属性 (Attribute)。若要使用这些对象,请将 XmlAnyElementAttribute 应用到返回 XmlElement 对象数组的字段中,或者将 XmlAnyAttributeAttribute 应用到返回 XmlAttribute 对象数组的字段中。

如果属性 (Property) 或字段返回一个复杂对象(如数组或类实例),则 XmlSerializer 将其转换为嵌套在主 XML 文档内的元素。例如,以下代码中的第一个类返回第二个类的实例。

XmlSerializer默认的序列化规则

对于一般的数据对象(这里就用上面的Person类来说明),使用XmlSerializer对其进行序列化后会生成怎样的XML结构。首先定义一个辅助方法专门进行基于XmlSerializer的序列化操作。

1  static void Serialize<T>(T instance, string fileName)
2         {
3             using (XmlWriter writer = new XmlTextWriter(fileName, Encoding.UTF8))
4             {
5                 XmlSerializer serializer = new XmlSerializer(typeof(T));
6                 serializer.Serialize(writer, instance);
7             }
8         }

在控制台程序中,通过调用上面的Serialize<T>方法将创建的Person对象序列化保存在xml文件中。

1     static void Main(string[] args)
2         {
3             Person p = new Person("Wolfy", 24, Convert.ToDateTime("1989-04-11"));
4             Serialize<Person>(p, "person.xml");
5             Console.Read();
6         }

上面程序执行后,打开生成的person.xml文件,如下所示xml代表序列化后生成的xml结构。

<?xml version="1.0" encoding="utf-8"?><Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Name>Wolfy</Name><Age>24</Age><Birthday>1989-04-11T00:00:00</Birthday></Person>

从而得出XmlSerializer在默认的情况下的序列化规则:

  • XML根节点的名称为对象类型的名称,并且没有命名空间。
  • 对象属性或字段成员以XmlElement的形式输出,名称和属性/字段名称一致,并且不具有命名空间。
  • 只有public属性/字段成员才会参与序列化(private的字段并不会序列化)。
  • XmlEmlement的顺序与对应的属性或字段在类型中定义的顺序一致。

注意:这里同样得定义一个空的无参构造函数。这个函数是必须的,因为反序列化的时候需要调用它创建对象。如果将其从成员列表中移除,在序列化的时候会抛出InvalidOptionException异常,并提示"Person无法序列化因为它没有无参的构造函数"。

对于被序列化对象的属性,不仅要求是共有的,还要求是可读写的,如果将Person类中age和birthday分别改成只读/写的属性。如下:

 1  public int Age
 2         {
 3             get { return age; }
 4             //set { age = value; }
 5         }
 6         private DateTime birthday;
 7
 8         public DateTime Birthday
 9         {
10             //get { return birthday; }
11             set { birthday = value; }
12         }

执行控制台程序,执行结果如下,可见只读、写的age和birthday并没有出现在序列化的xml中。

<?xml version="1.0" encoding="utf-8"?><Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Name>Wolfy</Name></Person>

如果是自定义自动实现的属性,定义成下面的这两种方式,Person对象是不能被序列化的

通过定制XmlSerializer控制XML结构

上面列出的仅仅是XmlSerializer采用的默认序列化规则。在很多情况下,我们需要序列化生成的XML符合一个既定的XSD,那么就需要对xmlSerializer的序列化进行人工的干预和控制。

对最终生成的XML结构的控制可以通过在数据类型和它的字段/属性成员上应用相应的特性来实现。

  • 在类型上应用XmlRootAttribute特性,通过Name和Namespace属性改变根节点的名称和命名空间。
  • 在字段/属性上应用System.Xml.Serialization.XmlAttributeAttribute特性将其序列化成XML属性,同时通过AttributeName和Namespace属性指定XML属性的名称和命名空间。
  • 在字段/属性上应用System.Xml.Serialization.XmlAttributeAttribute特性将其序列化成XML元素,同时通过AttributeName、Namespace和Order属性指定XML属性的名称和命名空间和先后次序。

我们可以按照如下的方式在类型上应用XmlRootAttribute特性对ElementName和Namespace属性进行相应的设置最终控制根节点的元素名称和命名空间。在属性Name上应用XmlAttributeAttrubute特性让该属性以XML属性的形式被序列化。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
namespace Wolfy.XmlSerializerDemo
{
    [XmlRoot(ElementName = "Per", Namespace = "http://www.artech.com")]
    public class Person
    {
        public Person() { }
        public Person(string name, int age, DateTime bithday)
        {
            this.name = name;
            this.age = age;
            this.birthday = bithday;
        }
        private string name;
        [XmlAttribute]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        private int age;

        public int Age
        {
            get { return age; }
            set { age = value; }
        }
        private DateTime birthday;

        public DateTime Birthday
        {
            get { return birthday; }
            set { birthday = value; }
        }
    }
}

Person

生成的xml文件:

<?xml version="1.0" encoding="utf-8"?><Per xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Name="Wolfy" xmlns="http://www.artech.com"><Age>24</Age><Birthday>1989-04-11T00:00:00</Birthday></Per>

反序列化通用方法:

1  static T Desirialize<T>(string fileName)
2         {
3             using (FileStream fs = new FileStream(fileName, FileMode.Open))
4             {
5                 XmlSerializer serializer = new XmlSerializer(typeof(T));
6                 return (T)serializer.Deserialize(fs);
7             }
8
9         }

参考文献:

MSDN:

http://msdn.microsoft.com/zh-cn/library/system.xml.serialization.xmlserializer(VS.80).aspx

http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx

《WCF全面解析 上册》蒋金楠 著 电子工业出版社

关于序列化先总结到这里,关于DataContractSerializer之后会用专门一篇来总结。

自己不是大牛,但是也说的上一个进击的小菜......

时间: 2024-11-07 07:59:30

序列化和反序列化的几种方式(JavaScriptSerializer 、XmlSerializer、DataContractSerializer)(一)的相关文章

序列化和反序列化的几种方式(DataContractSerializer)(二)

DataContractSerializer 类 使用提供的数据协定,将类型实例序列化和反序列化为 XML 流或文档. 无法继承此类. 命名空间: System.Runtime.Serialization 程序集:  System.Runtime.Serialization(在 System.Runtime.Serialization.dll 中) 备注 使用 DataContractSerializer 类可以将类型实例序列化和反序列化为 XML 流或文档. 通过将 DataContractA

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

什么是JSON? JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write and easy for machines to parse and generate. JSON is a text format that is completely language independent. 翻译:Json[javascrip

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

在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 首先,解释一下json Json[javascript对象表示方法],它是一个轻量级的数据交换格式,我们可以很简单的来读取和写它,并且它很容易被计算机转化和生成,它是完全独立于语言的. Json支持下面两种数据结构: 键值对的集合--各种不同的编程语言,都支持这种数据结构: 有序的列表类型值的集合--这其中包含数组,集合,矢量,或者序列,等等. Json有下面几种表现形式 1.对象

.NET中JSON的序列化和反序列化的几种方式

一.什么是JSON JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式.它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据.简洁和清晰的层次结构使得JSON 成为理想的数据交换语言. 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率. 是JavaScript用来处理数据的一种格式,大部分是用来处理JavaScript和web服务器端之间的数据交换

序列化和反序列化及线程实现方式

一.序列化与反序列化       把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 序列化关键代码如下: 定义Person类实现序列化.重写toString方法,定义无参以及带参构造 定义类 public class MySerialize { public static void main(String[] args)

Json的序列化和反序列化

一.什么是Json:  Json[javascript对象表示方法],它是一个轻量级的数据交换格式,我们可以很简单的来读取和写它,并且它很容易被计算机转化和生成 二.Json的表现形式: 对象: var user = {"name":"fxhl","gender":"Male","qq":"1123166772"} 数组: var userlist = [{"user"

深度剖析PHP序列化和反序列化

序列化 序列化格式 在PHP中,序列化用于存储或传递 PHP 的值的过程中,同时不丢失其类型和结构. 序列化函数原型如下: string serialize ( mixed $value ) 先看下面的例子: class CC { public $data; private $pass; public function __construct($data, $pass) { $this->data = $data; $this->pass = $pass; } } $number = 34;

JSON 序列化和反序列化 In Go

笔者之前有写过关于 xml 的使用文章,今天来给大家介绍关于数据序列化和反序列化的一种常见方式 JSON. 尤其是在 http,rpc 的微服务调用中. 基础语法 在 Go 中我们主要使用官方的 encoding/json 包对 json 数据进行序列化和反序列化,主要使用方法有: 序列化: 反序列化: 简单的例子 当我们运行代码的时候可以得到如下输出结果: 在这个列子中,我们使用?unmarshal?和?marshal?将一个整数的 JSON 二进制转化为 go?int?数据 注意:在实际应用

第五节:控制序列化和反序列化的数据

本章前面讨论过,控制序列化和反序列化过程的最佳方式就是使用OnSerializing.OnSerialized.OnDeserializing.OnDeserialized.NonSerialized.OptionalField等attribute.然而,在一些极少见的情况下,这些attribute不能提供你希望的全部控制.除此之外,格式化器在内部使用了反射,而反射的速度比较慢,这会增大序列化和反序列化对象所化的时间.为了序列化/反序列化的数据进行完全的控制,并避免使用反射,你的类型可实现ISe