刚刚碰巧群里有人问这个问题,而之前的博客中并没有提及,打算弄一篇博客简单提及一下这个知识点。
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 + "\r\n");
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
}
}
如果程序没有发生异常,则可以在控制台项目bin\Debug目录下查看生成的张三.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}\n性别:{1}\n电话:{2}\n地址:{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在线安装示意图

点击界面右侧的安装按钮,进行安装。安装成功后,会在VS输出窗口看到安装过程。

安装完毕后,会为我们的控制台项目默认添加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}\n性别:{1}\n电话:{2}\n地址:{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}\n性别:{1}\n电话:{2}\n地址:{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}\n性别:{1}\n电话:{2}\n地址:{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
}
}