序列化和反序列化的几种方式(JavaScriptSerializer 、XmlSerializer、DataContractSerializer)(一)
JavaScriptSerializer 类
为启用 AJAX 的应用程序提供序列化和反序列化功能。
命名空间: System.Web.Script.Serialization
程序集: System.Web.Extensions(在 System.Web.Extensions.dll 中)
JavaScriptSerializer 类由异步通信层内部使用,用于序列化和反序列化在浏览器和 Web 服务器之间传递的数据。 您无法访问序列化程序的此实例。 但是,此类公开了公共 API。 因此,当您希望在托管代码中使用 JavaScript 对象符号 (JSON) 时可以使用此类。
若要序列化对象,请使用 Serialize 方法。 若要反序列化 JSON 字符串,请使用 Deserialize 或 DeserializeObject 方法。 若要序列化和反序列化 JavaScriptSerializer 本身不支持的类型,请使用 JavaScriptConverter 类来实现自定义转换器。 然后,使用 RegisterConverters 方法注册转换器。
关于Serialize和Deserialize的应用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
namespace Wolfy.SerializerDemo
{
class Program
{
static void Main(string[] args)
{
List<Person> persons = new List<Person>{
new Person("wolfy",,Convert.ToDateTime("1989-04-11")),
new Person("张三",,Convert.ToDateTime("1990-04-11")),
new Person("李四",,Convert.ToDateTime("1991-04-11")),
new Person("王五",,Convert.ToDateTime("1992-04-11"))
};
//创建JavaScriptSerializer对象
JavaScriptSerializer jss = new JavaScriptSerializer();
//调用序列化方法Serialize
string json = jss.Serialize(persons);
Console.WriteLine("序列化.....");
Console.WriteLine(json);
Console.WriteLine("反序列化.....");
JavaScriptSerializer jss2 = new JavaScriptSerializer();
List<Person> list = jss2.Deserialize<List<Person>>(json);
foreach (Person item in list)
{
Console.WriteLine(item.Name + "\t" + item.Age.ToString() + "\t" + item.Birthday);
} Console.Read();
}
}
}
Person类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.SerializerDemo
{
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; 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; }
}
}
}
运行结果:
注意: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转换的方式,具体方法如下:
在对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)、基元类型、数组,甚至 XmlElement 或 XmlAttribute 对象形式的嵌入 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 的灵活性。通过在强类型类中使用类型为 XmlElement、XmlAttribute 或 XmlNode 的字段或属性 (Property),可以将部分 XML 文档直接读入 XML 对象中。
如果使用扩展 XML 架构,则也可以使用 XmlAnyElementAttribute 和 XmlAnyAttributeAttribute 属性 (Attribute) 来序列化及反序列化在原始架构中找不到的元素或属性 (Attribute)。若要使用这些对象,请将 XmlAnyElementAttribute 应用到返回 XmlElement 对象数组的字段中,或者将 XmlAnyAttributeAttribute 应用到返回 XmlAttribute 对象数组的字段中。
如果属性 (Property) 或字段返回一个复杂对象(如数组或类实例),则 XmlSerializer 将其转换为嵌套在主 XML 文档内的元素。例如,以下代码中的第一个类返回第二个类的实例。
XmlSerializer默认的序列化规则
对于一般的数据对象(这里就用上面的Person类来说明),使用XmlSerializer对其进行序列化后会生成怎样的XML结构。首先定义一个辅助方法专门进行基于XmlSerializer的序列化操作。
static void Serialize<T>(T instance, string fileName)
{
using (XmlWriter writer = new XmlTextWriter(fileName, Encoding.UTF8))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(writer, instance);
}
}
在控制台程序中,通过调用上面的Serialize<T>方法将创建的Person对象序列化保存在xml文件中。
static void Main(string[] args)
{
Person p = new Person("Wolfy", , Convert.ToDateTime("1989-04-11"));
Serialize<Person>(p, "person.xml");
Console.Read();
}
上面程序执行后,打开生成的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分别改成只读/写的属性。如下:
public int Age
{
get { return age; }
//set { age = value; }
}
private DateTime birthday; public DateTime Birthday
{
//get { return birthday; }
set { birthday = value; }
}
执行控制台程序,执行结果如下,可见只读、写的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>
person.xml
反序列化通用方法:
static T Desirialize<T>(string fileName)
{
using (FileStream fs = new FileStream(fileName, FileMode.Open))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(fs);
} }
参考文献:
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之后会用专门一篇来总结。
自己不是大牛,但是也说的上一个进击的小菜......
序列化和反序列化的几种方式(JavaScriptSerializer 、XmlSerializer、DataContractSerializer)(一)的更多相关文章
- 序列化和反序列化的几种方式(DataContractSerializer)(二)
DataContractSerializer 类 使用提供的数据协定,将类型实例序列化和反序列化为 XML 流或文档. 无法继承此类. 命名空间: System.Runtime.Serializati ...
- 序列化和反序列化的几种方式(DataContractSerializer)
序列化和反序列化的几种方式(DataContractSerializer) DataContractSerializer 类 使用提供的数据协定,将类型实例序列化和反序列化为 XML 流或文档. 无法 ...
- 在C#中,Json的序列化和反序列化的几种方式总结
在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 什么是JSON? JSON (JavaScript Object Notation) ...
- 在C#中,Json的序列化和反序列化的几种方式总结 转载
转载自 https://www.cnblogs.com/caofangsheng/p/5687994.html 谢谢 在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据 ...
- C#中,Json的序列化和反序列化的几种方式总结
在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化Json数据到对象. 什么是JSON? JSON (JavaScript Object Notation) ...
- 在C#中,Json的序列化和反序列化的几种方式
摘自:http://www.cnblogs.com/caofangsheng/p/5687994.html 在这篇文章中,我们将会学到如何使用C#,来序列化对象成为Json格式的数据,以及如何反序列化 ...
- .NET中JSON的序列化和反序列化的几种方式
一.什么是JSON JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式.它基于ECMAScript(欧洲计算机协会制定的js规范)的一个子集 ...
- Json 序列化以及反序列化的三种方式(二)
1.什么是JSON? Json[javascript对象表示方法],它是一个轻量级的数据交换格式,我们可以很简单的来读取和写它,并且它很容易被计算机转化和生成,它是完全独立于语言的 2.Json支持下 ...
- golang的序列化与反序列化的几种方式
golang用来序列化的模块有很多,我们来介绍3个. json 首先登场的是json,这个几乎毋庸置疑. 序列化 package main import ( "encoding/json&q ...
随机推荐
- CVE
一.简介 CVE 的英文全称是"Common Vulnerabilities & Exposures"公共漏洞和暴露.CVE就好像是一个字典表,为广泛认同的信息安全漏洞或者 ...
- C++ 基本知识
无论父类与子类的析构函数是否是virutal,子类的析构函数都会调用父类的析构函数 调用构造函数是与构造函数顺序相反,先子类后基类,否则如果基类先析构,子类的有些资源已经不存在了,会出错. 在C++中 ...
- Zookeeper C API 指南一(转)
Zookeeper 监视(Watches) 简介 Zookeeper C API 的声明和描述在 include/zookeeper.h 中可以找到,另外大部分的 Zookeeper C API 常量 ...
- js对Date对象的操作的问题(生成一个倒数7天的数组)
今天在论坛上看到这样一个问题如下: 问题描述: 使用JavaScript生成一个倒数7天的数组.比如今天是10月1号,生成的数组是["9月25号","9月26号" ...
- UVA 103 Stacking Boxes --LIS
实际上是一个扩展维度的矩形嵌套问题. 一个物体能嵌入另一个物体中,当且仅当这个物体的所有维度的长度都小于另外一个(本题是小于等于),又因为可以旋转等变换,所以干脆将每个箱子的边从小到大排序,以便于判断 ...
- HDU 1565 最大点权独立集
首先要明白图论的几个定义: 点覆盖.最小点覆盖: 点覆盖集即一个点集,使得所有边至少有一个端点在集合里.或者说是“点” 覆盖了所有“边”.. 最小点覆盖(minimum vertex covering ...
- 关于comparable与comparator的用法(即自定义集合框架用法 )
package javastudy; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; ...
- Android性能测试工具Emmagee介绍
Emmagee介绍 Emmagee是监控指定被测应用在使用过程中占用机器的CPU.内存.流量资源的性能测试小工具.该工具的优势在于如同windows系统性能监视器类似,它提供的是数据采集的功能,而行为 ...
- Mac上安装node.js
1.下载node for mac并一路默认安装 2.测试成功否 3.copy this file to test(save as javascript file) var http = require ...
- Gitblit-Git版本服务器环境部署
Gitblit介绍 Gitblit 是一个纯 Java 库用来管理.查看和处理 Git 资料库.相当于 Git 的 Java 管理工具,支持linux系统. Git是分布式版本控制系统,它强调速度.数 ...