序列化和反序列化的几种方式(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 ...
随机推荐
- 如何定制你自己的jQuery
jQuery随着版本的不断升级代码量也随之增加,从1.0.0的不到两千行到现在的1.10.2已经突破1万行. 新的API不断增加,但有些在项目中并没有用到.jQuery团队很早就考虑到这一点,按模块来 ...
- 构建多模块的Maven项目
在Eclipse下创建一个maven项目,该项目有多个模块组成. 1.创建父项目 File->New->Project->Maven->Maven Project(图一) ...
- SDRAM总结
使用的流程 W9825G6JH winbond sdram 4M words X 4banks X 16bits=. Accesses to the SDRAM are burst oriented. ...
- POJ 1703 Find them,Catch them ----种类并查集(经典)
http://blog.csdn.net/freezhanacmore/article/details/8774033?reload 这篇讲解非常好,我也是受这篇文章的启发才做出来的. 代码: #i ...
- Adobe Scout 使用参考说明
Adobe Scout 用于优化 Flash 内容,是一款极为强大的工具,因为它能让您看到 Flash Player 幕后正在发生的事情.但是若明白 Flash Player 为什么做这些事情,您看到 ...
- JMeter学习参数化User Defined Variables与User Parameters
偶然发现JMeter中有两个元件(User Defined Variables与User Parameters)很相近,刚开始时我也没注意,两者有什么不同.使用时却发现两者使用场景有些不同,现在小结一 ...
- SQL Server 2005 安装图解教程(Windows)
因工作需要,好久未安装SQL Server2005,今天安装了一下,特此写下安装步骤留下笔记. 安装前准备: 先安装IIS,再安装SQL Server2005 一.安装 点击安装,如下图: 选择操作系 ...
- 工厂模式(Factory Patter)
1.工厂模式简介 工厂模式属于创建型模式,是专门用来创建对象的模式,抽象了实例化的过程.工厂模式分为 : 工厂方法模式.抽象工厂模式. 在学习工厂方法模式.抽象工厂之前,首先先要了解一下简单工厂模式, ...
- UICollectionView移动
collectionView在iOS9中发布了一个可以移动cell的新特性,实现如下: 1.创建collectionView并设置代理 - (UICollectionView *)collection ...
- iOS中NSLog的输出格式
%@ 对象%d %i 整数%u 无符整形%f 浮点/双字%x, %X 二进制整数%o 八进制整数%zu size_t%p 指针 ; NSLog(@"%p",&tem); & ...