ASP.NET Core MVC 从入门到精通之序列化
随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生,或其他想从事ASP.NET Core MVC 系统开发的人员。 经过前几篇文章的讲解,初步了解ASP.NET Core MVC项目创建,启动运行,以及命名约定,创建控制器,视图,模型,接收参数,传递数据ViewData,ViewBag,路由,页面布局,wwwroot和客户端库,Razor语法,EnityFrameworkCore与数据库,HttpContext,Request,Response,Session等内容,今天继续讲解ASP.NET Core MVC 中序列化等相关内容,仅供学习分享使用。什么是序列化和反序列化?
序列化是将对象状态转换为可保持或传输的形式的过程。 序列化的补集是反序列化,后者将流转换为对象。 这两个过程一起保证能够存储和传输数据。
序列化应用场景
在实际应用中,序列化和反序列化,并不局限于ASP.NET Core MVC项目,在其他类型的项目中,也比较常见。具体场景如下所示:
[*]将内存的对象序列化后保存在本地,上传到某些特定位置,如:共享目录,FTP,供第3方系统识别读取。
[*]与第3方进行通信,对方只能接收二进制类型字节流数据,
[*]保存Session,Cookie等场景
[*]跨平台,跨语言交互等场景
常见序列化格式
常见的序列化数据格式有:
[*]整体二进制,将实例对象整体序列化成二进制,
[*]xml格式,将实例对象序列化成XML数据格式,多用于WebService,
[*]json格式,将实例对象序列化成JSON文件格式,多用于WebAPI等Restful数据调用,
[*]Protobuf,即Protocol Buffers,是Google公司开发的一种跨语言和平台的序列化数据结构的方式,是一个灵活的、高效的用于序列化数据的协议。
序列化示例
在本示例中,为便于比较序列化后内容大小,将序列化后内容保存到本地文件,且实现了序列化和反序列化功能。
1. 安装第三方库
序列化JSON和Protobuf需要安装第三方库,可通过NuGet包管理器进行安装,如下所示:
2. 序列化帮助类接口
为了统一调用方式,特定义序列化帮助类接口,不同实现方式,只需实现对应接口即可,接口定义如下:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace ConsoleApp2
8 {
9 /// <summary>
10 /// 序列化帮助类接口
11 /// </summary>
12 public interface ISerializeHelper
13 {
14 /// <summary>
15 /// 序列化
16 /// </summary>
17 /// <typeparam name="T"></typeparam>
18 /// <param name="t"></param>
19 /// <param name="path">序列化后保存路径</param>
20 void Serialize<T>(T t, string path) where T : class;
21
22 /// <summary>
23 /// 反序列化
24 /// </summary>
25 /// <typeparam name="T"></typeparam>
26 /// <param name="path">反序列化文件路径</param>
27 /// <returns></returns>
28 T Deserialize<T>(string path) where T : class;
29 }
30 }
3. 定义序列化模型类Person
在本示例中,为了比较序列化格式的不同结果,定义一个测试类,如下所示:
1 using ProtoBuf;
2 using System;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7
8 namespace ConsoleApp2
9 {
10 /// <summary>
11 /// 个人信息
12 /// </summary>
13
14
15 public class Person
16 {
17 /// <summary>
18 /// 唯一标识
19 /// </summary>
20
21 public int Id { get; set; }
22
23 /// <summary>
24 /// 姓名
25 /// </summary>
26
27 public string Name { get; set; }
28
29 /// <summary>
30 /// 生日
31 /// </summary>
32
33 public DateTime Birthday { get; set; }
34
35 public override string ToString()
36 {
37 return $"Id={Id},Name={Name},Birthday={Birthday.ToString("yyyy-MM-dd HH:mm:ss.fff")}";
38 }
39
40 }
41 }注意:定义Person时,有以下2点需要注意:
[*]进行整体二进制序列化,必须将类标记为Serializable,否则会抛异常。
[*]Protobuf序列化需要将类标记为ProtoContract,并将需要序列化的属性标记为ProtoMember
4. 整体二进制
整体二进制是将实例对象整体序列化成二进制字节流,以及从二进制字节流反序列成实例对象,如下所示:
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using System.Runtime.Serialization.Formatters.Binary;
6 using System.Text;
7 using System.Threading.Tasks;
8
9 namespace ConsoleApp2
10 {
11 internal class BinHelper : ISerializeHelper
12 {
13 public T Deserialize<T>(string path) where T:class
14 {
15 string filePath = path;
16 T t;
17 using (FileStream fs = new FileStream(filePath, FileMode.Open))
18 {
19 BinaryFormatter bf = new BinaryFormatter();
20 t = bf.Deserialize(fs) as T;
21 }
22 return t;
23 }
24
25 public void Serialize<T>(T t, string path) where T : class
26 {
27 string filePath = path;
28 using (FileStream fs = new FileStream(filePath, FileMode.Create))
29 {
30 BinaryFormatter bf = new BinaryFormatter();
31 bf.Serialize(fs, t);
32 }
33 }
34 }
35 }
5. XML格式
XML是一种可扩展标记语言,多用于接口调用及数据传输,语言无关,曾经也是风靡一时,是接口开发的首选。序列化XML代码如下所示:
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7 using System.Xml.Serialization;
8
9 namespace ConsoleApp2
10 {
11 public class XmlHelper : ISerializeHelper
12 {
13 public T Deserialize<T>(string path) where T : class
14 {
15 string filePath = path;
16 T t;
17 using (FileStream fs = new FileStream(filePath, FileMode.Open))
18 {
19 XmlSerializer serializer = new XmlSerializer(typeof(Person));
20 object obj = serializer.Deserialize(fs);
21 t = obj as T;
22 }
23 return t;
24 }
25
26 public void Serialize<T>(T t, string path) where T : class
27 {
28 string filePath = path;
29 using (FileStream fs = new FileStream(filePath, FileMode.Create))
30 {
31 XmlSerializer serializer = new XmlSerializer(typeof(Person));
32 serializer.Serialize(fs, t);
33 }
34 }
35 }
36 }
6. JSON格式
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,可使人们很容易地进行阅读和编写,同时也方便了机器进行解析和生成。JSON适用于进行数据交互的场景,如网站前台与后台之间的数据交互。JSON是比XML更简单的一种数据交换格式,它采用完全独立于编程语言的文本格式来存储和表示数据。序列化JSON一般采用第3方库Newtonsoft.Json来实现,具体代码如下所示:
1 using Newtonsoft.Json;
2 using System;
3 using System.Collections.Generic;
4 using System.IO;
5 using System.Linq;
6 using System.Text;
7 using System.Threading.Tasks;
8
9 namespace ConsoleApp2
10 {
11 internal class JsonHelper : ISerializeHelper
12 {
13 public T Deserialize<T>(string path) where T : class
14 {
15 T t;
16 using (StreamReader file = File.OpenText(path))
17 {
18 JsonSerializer serializer = new JsonSerializer();
19 t = (T)serializer.Deserialize(file, typeof(T));
20
21 }
22 return t;
23 }
24
25 public void Serialize<T>(T t, string path) where T : class
26 {
27 using (StreamWriter file = File.CreateText(path))
28 {
29 JsonSerializer serializer = new JsonSerializer();
30 serializer.Serialize(file, t);
31 }
32 }
33 }
34 }
7. Protobuf格式
Protobuf即Protocol Buffers,是Google公司开发的一种跨语言和平台的序列化数据结构的方式,是一个灵活的、高效的用于序列化数据的协议。与XML和JSON格式相比,protobuf更小、更快、更便捷。序列化Protobuf格式代码如下:
1 using ProtoBuf;
2 using System;
3 using System.Collections.Generic;
4 using System.IO;
5 using System.Linq;
6 using System.Runtime.Serialization.Formatters.Binary;
7 using System.Text;
8 using System.Threading.Tasks;
9
10 namespace ConsoleApp2
11 {
12 internal class ProtobufHelper : ISerializeHelper
13 {
14 public T Deserialize<T>(string path) where T : class
15 {
16 string filePath = path;
17 T t;
18 using (FileStream fs = new FileStream(filePath, FileMode.Open))
19 {
20 t = Serializer.Deserialize<T>(fs);
21 }
22 return t;
23 }
24
25 public void Serialize<T>(T t, string path) where T : class
26 {
27 string filePath = path;
28 using (FileStream fs = new FileStream(filePath, FileMode.Create))
29 {
30 Serializer.Serialize<T>(fs, t);
31 }
32 }
33 }
34 }
8. 实例测试
对同一个对象,进行不同格式的序列化,如下所示:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace ConsoleApp2
8 {
9 internal class Program
10 {
11 static void Main(string[] args)
12 {
13 Person person = new Person()
14 {
15 Id = 1,
16 Name = "公子小六",
17 Birthday = DateTime.Now,
18 };
19 //bin格式序列化
20 var binHelper = new BinHelper();
21 string binPath = @"D:\serialize\person.bin";
22 binHelper.Serialize<Person>(person, binPath);
23
24 //xml格式序列化
25 var xmlHelper = new XmlHelper();
26 string xmlPath = @"D:\serialize\person.xml";
27 xmlHelper.Serialize<Person>(person, xmlPath);
28
29 //json格式序列化
30 var jsonHelper = new JsonHelper();
31 string jsonPath = @"D:\serialize\person.json";
32 jsonHelper.Serialize<Person>(person, jsonPath);
33
34 //protobuf格式序列化
35 var protoHelper= new ProtobufHelper();
36 var protoPath = @"D:\serialize\person.proto";
37 protoHelper.Serialize<Person>(person, protoPath);
38 }
39 }
40 }反序列化,将本地文件反序列化成内存对象,如下所示:
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 namespace ConsoleApp2
8 {
9 internal class Program
10 {
11 static void Main(string[] args)
12 {
13 //bin格式反序列化
14 var binHelper = new BinHelper();
15 string binPath = @"D:\serialize\person.bin";
16 var p1 = binHelper.Deserialize<Person>(binPath);
17 //xml格式反序列化
18 var xmlHelper = new XmlHelper();
19 string xmlPath = @"D:\serialize\person.xml";
20 var p2 = xmlHelper.Deserialize<Person>(xmlPath);
21 //json格式反序列化
22 var jsonHelper = new JsonHelper();
23 string jsonPath = @"D:\serialize\person.json";
24 var p3 = jsonHelper.Deserialize<Person>(jsonPath);
25 //protobuf格式反序列化
26 var protoHelper= new ProtobufHelper();
27 var protoPath = @"D:\serialize\person.proto";
28 var p4= protoHelper.Deserialize<Person>(protoPath);
29
30 Console.WriteLine($"p1:{p1}");
31 Console.WriteLine($"p2:{p2}");
32 Console.WriteLine($"p3:{p3}");
33 Console.WriteLine($"p4:{p4}");
34 }
35 }
36 }
37
序列化大小比较
序列化后保存到本地的文件,如下所示:
对Person按不同格式序列化后的本地文件大小进行比较,具体如下:
[*]整体二进制格式:person.bin 225字节
[*]XML格式:person.xml 242字节
[*]JSON格式:person.json 77字节
[*]Protobuf格式:person.proto 29字节
经过比较,Proto最小,XML最大,所以在对于大小要求比较严格的场景,可优先考虑Protobuf格式。
以上就是ASP.NET Core MVC 从入门到精通之序列化的全部内容。
来源:https://www.cnblogs.com/hsiang/archive/2023/05/07/17378782.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页:
[1]