第二十一章 数据访问(In .net4.5) 之 序列化
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) 之 序列化的更多相关文章
- 第二十二章 数据访问(In .net4.5) 之 集合
1. 概述 本章内容包括 .net平台中的集合.如何选择集合 以及 如何实现自定义集合. 2. 主要内容 2.1 使用数组(Array) ]; ; x < arrayOfInt.Length; ...
- 第十九章 数据访问(In .net4.5) 之 处理数据
1. 概述 本章介绍 数据库.Json和Xml.web services 三种介质上的数据操作. 2. 主要内容 2.1 数据库 ① 建立连接 .net平台中的数据连接类都继承自DbConnectio ...
- JavaScript高级程序设计:第二十一章
第二十一章 Ajax与Comet 一.XMLHttpRequest对象 1.XHT的用法 在使用XHR对象时,要调用的第一个方法时open( ),它接受3个参数:要发送的请求的类型.请求的URL和表示 ...
- 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(二) controller
原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 开涛shiro教程-第二十一章-授予身份与切换身份(二) 1.回顾 ...
- 2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(一) table、entity、service、dao
原博客地址:http://jinnianshilongnian.iteye.com/blog/2018398 根据下载的pdf学习. 第二十一章 授予身份与切换身份(一) 1.使用场景 某个领导因为某 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION)
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第二十一章:环境光遮蔽(AMBIENT OCCLUSION) 学习目标 ...
- Flask 教程 第二十一章:用户通知
本文翻译自The Flask Mega-Tutorial Part XXI: User Notifications 这是Flask Mega-Tutorial系列的第二十一章,我将添加一个私有消息功能 ...
- Gradle 1.12用户指南翻译——第二十一章. Gradle 插件
昨天晚上只顾着和女朋友看<匆匆那年>电视剧的最后几集,所以说好的Android文档<Gradle 插件用户指南>第五章自然也没翻译多少.所以今天也发不了第五章的翻译了,就发几个 ...
- 第二十一章 Django的分页与cookie
第二十一章 Django的分页与cookie 第一课 模板 1.模板的继承 在Template目录下新建模板master.html <!DOCTYPE html> <html lan ...
随机推荐
- jQuery基础---filter()和find()
这是jQuery里常用的2个方法.他们2者功能是完全不同的,而初学者往往会被误导. 首先 我们看.find()方法:现在有一个页面,里面HTML代码为;程序代码 <div class=" ...
- Spark Standalone模式伪分布式环境搭建
前提:安装好jdk1.7,hadoop 安装步骤: 1.安装scala 下载地址:http://www.scala-lang.org/download/ 配置环境变量: export SCALA_HO ...
- windows下忘记mysql密码怎么办
长时间不用mysql,密码忘记了怎么办,按照下面的步骤可以重新设置密码: 1.先把mysql服务停了,右键计算机-->选择管理-->选择服务和应用程序-->选择服务-->找到m ...
- c# 清空txt文本文件的值
FileStream fs1 = null; try { fs1 = new FileStream(@"C:\db.txt", FileMode.Truncate, FileAcc ...
- EXTJS 6 新特性(译文)
Extjs 新特性 简介 使用extjs,sencha 团队开发一个简单的框架,可以为创建在任何类型设备上运行的应用,从手机端到平板电脑再到桌面应用,你将能够产生最佳的用户体验,编写更少的代码量,结合 ...
- 学习总结 初步了解HTML课程
HTML 内容(超文本标记语言) CSS 网页美化 Javascript 脚本语言 <html> --开始标签 <head> 网页上的控制信息 < ...
- 也谈LBP
LBP(local banary patter)是一种非常经典的用来描述图像局部纹理特征的算子. 1,基本LBP LBP方法自1994年提出,此后就作为一个有效的纹理特征,不断的被人使用和改进.LBP ...
- MongoDB 3: 使用中的问题,及其应用场景
导读:用MongoDB去存储非关系型的数据,是一个比较正确的选择.但是,如果只是用MongoDB,那么也会出现一些问题.MongoDB,尤其使用的最佳场景,更多的时候,需要结合关系型数据库共同解决问题 ...
- Loadrunner:error -86401 Failed to connceted xxx.xxx.xxx.xxx:25问题解决
[转自:http://www.51testing.com/html/00/130600-3578408.html]windows 2003上安装的LoadRunner11做为负载机在SMTP协议压测时 ...
- JS常用的设计模式(10)——模版方法模式
模式方法是预先定义一组算法,先把算法的不变部分抽象到父类,再将另外一些可变的步骤延迟到子类去实现.听起来有点像工厂模式( 非前面说过的简单工厂模式 ). 最大的区别是,工厂模式的意图是根据子类的实现最 ...