刚刚碰巧群里有人问这个问题,而之前的博客中并没有提及,打算弄一篇博客简单提及一下这个知识点。
MSDN文档中提及了序列化、反序列化的概念,这里引用一下。
序列化:将对象状态转换为可保持或传输的形式的过程。
反序列化:是序列化的逆过程,就是将流转换为对象的过程。
这两个过程一起保证数据易于传输和存储。
详细的请参考:http://msdn.microsoft.com/zh-cn/library/7ay27kt9(v=vs.100).aspx。
下面直接给出完整的代码,该代码演示了如何序列化一个对象以及反序列化(还原对象)的过程。
namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Object student = new Student() { StudentID = "007", StudentName = "guwei4037" }; string result = ObjectToString<Object>(student); Console.WriteLine(result + " "); Student newResult = StringToObject<Student>(result); Console.WriteLine("ID:{0}, Name:{1}", newResult.StudentID, newResult.StudentName); } /// <summary> /// 对象转字符串(序列化后转Base64编码字符串) /// </summary> /// <param name="obj">对象</param> /// <returns>字符串</returns> public static string ObjectToString<T>(T obj) { using (MemoryStream stream = new MemoryStream()) { IFormatter formatter = new BinaryFormatter(); formatter.Serialize(stream, obj); stream.Position = 0; byte[] buffer = new byte[stream.Length]; stream.Read(buffer, 0, buffer.Length); return Convert.ToBase64String(buffer); } } /// <summary> /// 字符串转对象(Base64编码字符串反序列化为对象) /// </summary> /// <param name="str">字符串</param> /// <returns>对象</returns> public static T StringToObject<T>(string str) { using (MemoryStream stream = new MemoryStream()) { byte[] bytes = Convert.FromBase64String(str); stream.Write(bytes, 0, bytes.Length); stream.Position = 0; IFormatter formatter = new BinaryFormatter(); return (T)formatter.Deserialize(stream); } } } /// <summary> /// 可序列化的类,用Serializable标示此类可序列化 /// </summary> [Serializable] public class Student { public string StudentID { get; set; } public string StudentName { get; set; } } }
运行结果截图:
XML序列化
示例:用XmlSerializer序列化一个学生对象。
namespace Test { class Program { static void Main(string[] args) { Student zhang3 = new Student() { Name = "张三", Sex = Sex.Male, Phone = "13012345678", Address = "中国" }; using (FileStream stream = new FileStream("张三.xml", FileMode.OpenOrCreate)) { XmlSerializer s = new XmlSerializer(typeof(Student)); s.Serialize(stream, zhang3); } Console.WriteLine("对象序列化成功..."); } } public class Student { public string Name { get; set; } public Sex Sex { get; set; } public string Phone { get; set; } public string Address { get; set; } } public enum Sex { Female, Male } }
如果程序没有发生异常,则可以在控制台项目binDebug目录下查看生成的张三.xml文件内容。
<?xml version="1.0"?> <Student xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Name>张三</Name> <Sex>Male</Sex> <Phone>13012345678</Phone> <Address>中国</Address> </Student>
XML反序列化
示例:将上个例子中生成的张三.xml文件反序列化为C#中的张三对象。
namespace Test { class Program { static void Main(string[] args) { XmlSerializer d = new XmlSerializer(typeof(Student)); using (FileStream stream = new FileStream("张三.xml", FileMode.OpenOrCreate)) { object obj = d.Deserialize(stream); if (obj is Student) { Student zhang3 = obj as Student; Console.WriteLine("姓名:{0} 性别:{1} 电话:{2} 地址:{3}", zhang3.Name, zhang3.Sex, zhang3.Phone, zhang3.Address); } } } } public class Student { public string Name { get; set; } public Sex Sex { get; set; } public string Phone { get; set; } public string Address { get; set; } } public enum Sex { Female, Male } }
JSON序列化
Ø JavaScriptSerializer
使用JavaScriptSerializer需要在项目中添加引用System.Web.Extensions,然后引用命名空间System.Web.Script.Serialization。
示例:使用JavaScriptSerializer将张三对象序列化为JSON字符串
using System.Web.Script.Serialization; namespace Test { class Program { static void Main(string[] args) { Student zhang3 = new Student() { Name = "张三", Sex = Sex.Male, Phone = "13012345678", Address = "中国" }; JavaScriptSerializer j = new JavaScriptSerializer(); string zhang3Json = j.Serialize(zhang3); Console.WriteLine(zhang3Json); } } public class Student { public string Name { get; set; } public Sex Sex { get; set; } public string Phone { get; set; } public string Address { get; set; } } public enum Sex { Female, Male } }
Ø DataContractJsonSerializer
使用DataContractJsonSerializer需要在项目中添加引用System.Runtime.Serialization,然后引用命名空间System.Runtime.Serialization.Json。
示例:使用DataContractJsonSerializer将张三对象序列化为JSON字符串
using System.Runtime.Serialization.Json; namespace Test { class Program { static void Main(string[] args) { Student zhang3 = new Student() { Name = "张三", Sex = Sex.Male, Phone = "13012345678", Address = "中国" }; DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(Student)); using (FileStream fs = new FileStream("张三.json", FileMode.OpenOrCreate)) { s.WriteObject(fs, zhang3); } } } public class Student { public string Name { get; set; } public Sex Sex { get; set; } public string Phone { get; set; } public string Address { get; set; } } public enum Sex { Female, Male } }
序列化完成后,可以在项目的bin/Debug目录下看到生成的张三.json文件。用notepad++等文本编辑器打开可以看到生成的json内容。
张三.json文件内容:
{"Address":"中国","Name":"张三","Phone":"13012345678","Sex":1}
Ø Json.NET
示例:使用Json.NET需要添加引用Newtonsoft.Json,可以通过nuget在线安装或者直接下载Newtonsoft.Json开发包添加引用。
通过nuget在线安装示意图
安装完毕后,会为我们的控制台项目默认添加Newtonsoft.Json引用。
示例:使用Json.NET序列化张三对象为Json字符串
using Newtonsoft.Json; namespace Test { class Program { static void Main(string[] args) { Student zhang3 = new Student() { Name = "张三", Sex = Sex.Male, Phone = "13012345678", Address = "中国" }; //序列化 string zhang3Json = JsonConvert.SerializeObject(zhang3); //输出结果:{"Name":"张三","Sex":1,"Phone":"13012345678","Address":"中国"} Console.WriteLine(zhang3Json); } } public class Student { public string Name { get; set; } public Sex Sex { get; set; } public string Phone { get; set; } public string Address { get; set; } } public enum Sex { Female, Male } }
可以看到输出结果中,Sex的值为1,并不是之前的Male。这是由于Json.NET在处理枚举时会默认将枚举元素的值输出。可以通过给枚举添加属性声明的方式输出枚举元素的名称。
将Student类修改如下:
public class Student { public string Name { get; set; } [JsonConverter(typeof(StringEnumConverter))] public Sex Sex { get; set; } public string Phone { get; set; } public string Address { get; set; } }
引用StringEnumConverter类需要添加Newtonsoft.Json.Converters命名空间。通过如上的修改输出序列化JSON字符串时会得到枚举的名称。
JSON反序列化
Ø JavaScriptSerializer
示例:使用JavaScriptSerializer将张三序列化生成的JSON字符串反序列化为张三对象
using System.Web.Script.Serialization; namespace Test { class Program { static void Main(string[] args) { Student zhang3 = new Student() { Name = "张三", Sex = Sex.Male, Phone = "13012345678", Address = "中国" }; JavaScriptSerializer j = new JavaScriptSerializer(); //序列化zhang3对象 string zhang3Json = j.Serialize(zhang3); //反序列化zhang3对象 Student zhang3FromJson = j.Deserialize<Student>(zhang3Json); Console.WriteLine("姓名:{0} 性别:{1} 电话:{2} 地址:{3}", zhang3FromJson.Name, zhang3FromJson.Sex, zhang3FromJson.Phone, zhang3FromJson.Address); } } public class Student { public string Name { get; set; } public Sex Sex { get; set; } public string Phone { get; set; } public string Address { get; set; } } public enum Sex { Female, Male } }
Ø DataContractJsonSerializer
示例:使用DataContractJsonSerializer将张三.json文件反序列化为张三对象。
using System.Runtime.Serialization.Json; namespace Test { class Program { static void Main(string[] args) { DataContractJsonSerializer s = new DataContractJsonSerializer(typeof(Student)); using (FileStream fs = new FileStream("张三.json", FileMode.OpenOrCreate)) { object obj = s.ReadObject(fs); if (obj is Student) { Student zhang3FromJson = obj as Student; Console.WriteLine("姓名:{0} 性别:{1} 电话:{2} 地址:{3}", zhang3FromJson.Name, zhang3FromJson.Sex, zhang3FromJson.Phone, zhang3FromJson.Address); } } } } public class Student { public string Name { get; set; } public Sex Sex { get; set; } public string Phone { get; set; } public string Address { get; set; } } public enum Sex { Female, Male } }
Ø Json.NET
示例:将张三的JSON字符串反序列化为张三对象
using Newtonsoft.Json; using Newtonsoft.Json.Converters; namespace Test { class Program { static void Main(string[] args) { Student zhang3 = new Student() { Name = "张三", Sex = Sex.Male, Phone = "13012345678", Address = "中国" }; //序列化 string zhang3Json = JsonConvert.SerializeObject(zhang3); //反序列化 Student zhang3FromJson = JsonConvert.DeserializeObject<Student>(zhang3Json); Console.WriteLine("姓名:{0} 性别:{1} 电话:{2} 地址:{3}", zhang3FromJson.Name, zhang3FromJson.Sex, zhang3FromJson.Phone, zhang3FromJson.Address); } } public class Student { public string Name { get; set; } [JsonConverter(typeof(StringEnumConverter))] public Sex Sex { get; set; } public string Phone { get; set; } public string Address { get; set; } } public enum Sex { Female, Male } }