翼度科技»论坛 编程开发 .net 查看内容

ASP.NET Core MVC 从入门到精通之序列化

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
随着技术的发展,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. 1 using System;
  2. 2 using System.Collections.Generic;
  3. 3 using System.Linq;
  4. 4 using System.Text;
  5. 5 using System.Threading.Tasks;
  6. 6
  7. 7 namespace ConsoleApp2
  8. 8 {
  9. 9     /// <summary>
  10. 10     /// 序列化帮助类接口
  11. 11     /// </summary>
  12. 12     public interface ISerializeHelper
  13. 13     {
  14. 14         /// <summary>
  15. 15         /// 序列化
  16. 16         /// </summary>
  17. 17         /// <typeparam name="T"></typeparam>
  18. 18         /// <param name="t"></param>
  19. 19         /// <param name="path">序列化后保存路径</param>
  20. 20         void Serialize<T>(T t, string path) where T : class;
  21. 21
  22. 22         /// <summary>
  23. 23         /// 反序列化
  24. 24         /// </summary>
  25. 25         /// <typeparam name="T"></typeparam>
  26. 26         /// <param name="path">反序列化文件路径</param>
  27. 27         /// <returns></returns>
  28. 28         T Deserialize<T>(string path) where T : class;
  29. 29     }
  30. 30 }
复制代码
 
3. 定义序列化模型类Person

 
在本示例中,为了比较序列化格式的不同结果,定义一个测试类,如下所示:
  1. 1 using ProtoBuf;
  2. 2 using System;
  3. 3 using System.Collections.Generic;
  4. 4 using System.Linq;
  5. 5 using System.Text;
  6. 6 using System.Threading.Tasks;
  7. 7
  8. 8 namespace ConsoleApp2
  9. 9 {
  10. 10     /// <summary>
  11. 11     /// 个人信息
  12. 12     /// </summary>
  13. 13     [ProtoContract]
  14. 14     [Serializable]
  15. 15     public class Person
  16. 16     {
  17. 17         /// <summary>
  18. 18         /// 唯一标识
  19. 19         /// </summary>
  20. 20         [ProtoMember(1)]
  21. 21         public int Id { get; set; }
  22. 22
  23. 23         /// <summary>
  24. 24         /// 姓名
  25. 25         /// </summary>
  26. 26         [ProtoMember(2)]
  27. 27         public string Name { get; set; }
  28. 28
  29. 29         /// <summary>
  30. 30         /// 生日
  31. 31         /// </summary>
  32. 32         [ProtoMember(3)]
  33. 33         public DateTime Birthday { get; set; }
  34. 34
  35. 35         public override string ToString()
  36. 36         {
  37. 37             return $"Id={Id},Name={Name},Birthday={Birthday.ToString("yyyy-MM-dd HH:mm:ss.fff")}";
  38. 38         }
  39. 39
  40. 40     }
  41. 41 }
复制代码
注意:定义Person时,有以下2点需要注意:

  • 进行整体二进制序列化,必须将类标记为Serializable,否则会抛异常。
  • Protobuf序列化需要将类标记为ProtoContract,并将需要序列化的属性标记为ProtoMember
 
4. 整体二进制

 
整体二进制是将实例对象整体序列化成二进制字节流,以及从二进制字节流反序列成实例对象,如下所示:
  1. 1 using System;
  2. 2 using System.Collections.Generic;
  3. 3 using System.IO;
  4. 4 using System.Linq;
  5. 5 using System.Runtime.Serialization.Formatters.Binary;
  6. 6 using System.Text;
  7. 7 using System.Threading.Tasks;
  8. 8
  9. 9 namespace ConsoleApp2
  10. 10 {
  11. 11     internal class BinHelper : ISerializeHelper
  12. 12     {
  13. 13         public T Deserialize<T>(string path) where T:class
  14. 14         {
  15. 15             string filePath = path;
  16. 16             T t;
  17. 17             using (FileStream fs = new FileStream(filePath, FileMode.Open))
  18. 18             {
  19. 19                 BinaryFormatter bf = new BinaryFormatter();
  20. 20                 t = bf.Deserialize(fs) as T;
  21. 21             }
  22. 22             return t;
  23. 23         }
  24. 24
  25. 25         public void Serialize<T>(T t, string path) where T : class
  26. 26         {
  27. 27             string filePath = path;
  28. 28             using (FileStream fs = new FileStream(filePath, FileMode.Create))
  29. 29             {
  30. 30                 BinaryFormatter bf = new BinaryFormatter();
  31. 31                 bf.Serialize(fs, t);
  32. 32             }
  33. 33         }
  34. 34     }
  35. 35 }
复制代码
 
5. XML格式

 
XML是一种可扩展标记语言,多用于接口调用及数据传输,语言无关,曾经也是风靡一时,是接口开发的首选。序列化XML代码如下所示:
  1. 1 using System;
  2. 2 using System.Collections.Generic;
  3. 3 using System.IO;
  4. 4 using System.Linq;
  5. 5 using System.Text;
  6. 6 using System.Threading.Tasks;
  7. 7 using System.Xml.Serialization;
  8. 8
  9. 9 namespace ConsoleApp2
  10. 10 {
  11. 11     public class XmlHelper : ISerializeHelper
  12. 12     {
  13. 13         public T Deserialize<T>(string path) where T : class
  14. 14         {
  15. 15             string filePath = path;
  16. 16             T t;
  17. 17             using (FileStream fs = new FileStream(filePath, FileMode.Open))
  18. 18             {
  19. 19                 XmlSerializer serializer = new XmlSerializer(typeof(Person));
  20. 20                 object obj = serializer.Deserialize(fs);
  21. 21                 t = obj as T;
  22. 22             }
  23. 23             return t;
  24. 24         }
  25. 25
  26. 26         public void Serialize<T>(T t, string path) where T : class
  27. 27         {
  28. 28             string filePath = path;
  29. 29             using (FileStream fs = new FileStream(filePath, FileMode.Create))
  30. 30             {
  31. 31                 XmlSerializer serializer = new XmlSerializer(typeof(Person));
  32. 32                 serializer.Serialize(fs, t);
  33. 33             }
  34. 34         }
  35. 35     }
  36. 36 }
复制代码
 
6. JSON格式

 
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,可使人们很容易地进行阅读和编写,同时也方便了机器进行解析和生成。JSON适用于进行数据交互的场景,如网站前台与后台之间的数据交互。JSON是比XML更简单的一种数据交换格式,它采用完全独立于编程语言的文本格式来存储和表示数据。序列化JSON一般采用第3方库Newtonsoft.Json来实现,具体代码如下所示:
  1. 1 using Newtonsoft.Json;
  2. 2 using System;
  3. 3 using System.Collections.Generic;
  4. 4 using System.IO;
  5. 5 using System.Linq;
  6. 6 using System.Text;
  7. 7 using System.Threading.Tasks;
  8. 8
  9. 9 namespace ConsoleApp2
  10. 10 {
  11. 11     internal class JsonHelper : ISerializeHelper
  12. 12     {
  13. 13         public T Deserialize<T>(string path) where T : class
  14. 14         {
  15. 15             T t;
  16. 16             using (StreamReader file = File.OpenText(path))
  17. 17             {
  18. 18                 JsonSerializer serializer = new JsonSerializer();
  19. 19                 t = (T)serializer.Deserialize(file, typeof(T));
  20. 20
  21. 21             }
  22. 22             return t;
  23. 23         }
  24. 24
  25. 25         public void Serialize<T>(T t, string path) where T : class
  26. 26         {
  27. 27             using (StreamWriter file = File.CreateText(path))
  28. 28             {
  29. 29                 JsonSerializer serializer = new JsonSerializer();
  30. 30                 serializer.Serialize(file, t);
  31. 31             }
  32. 32         }
  33. 33     }
  34. 34 }
复制代码
 
7. Protobuf格式

 
Protobuf即Protocol Buffers,是Google公司开发的一种跨语言和平台的序列化数据结构的方式,是一个灵活的、高效的用于序列化数据的协议。与XML和JSON格式相比,protobuf更小、更快、更便捷。序列化Protobuf格式代码如下:
  1. 1 using ProtoBuf;
  2. 2 using System;
  3. 3 using System.Collections.Generic;
  4. 4 using System.IO;
  5. 5 using System.Linq;
  6. 6 using System.Runtime.Serialization.Formatters.Binary;
  7. 7 using System.Text;
  8. 8 using System.Threading.Tasks;
  9. 9
  10. 10 namespace ConsoleApp2
  11. 11 {
  12. 12     internal class ProtobufHelper : ISerializeHelper
  13. 13     {
  14. 14         public T Deserialize<T>(string path) where T : class
  15. 15         {
  16. 16             string filePath = path;
  17. 17             T t;
  18. 18             using (FileStream fs = new FileStream(filePath, FileMode.Open))
  19. 19             {
  20. 20                 t = Serializer.Deserialize<T>(fs);
  21. 21             }
  22. 22             return t;
  23. 23         }
  24. 24
  25. 25         public void Serialize<T>(T t, string path) where T : class
  26. 26         {
  27. 27             string filePath = path;
  28. 28             using (FileStream fs = new FileStream(filePath, FileMode.Create))
  29. 29             {
  30. 30                 Serializer.Serialize<T>(fs, t);
  31. 31             }
  32. 32         }
  33. 33     }
  34. 34 }
复制代码
 
8. 实例测试

 
对同一个对象,进行不同格式的序列化,如下所示:
  1. 1 using System;
  2. 2 using System.Collections.Generic;
  3. 3 using System.Linq;
  4. 4 using System.Text;
  5. 5 using System.Threading.Tasks;
  6. 6
  7. 7 namespace ConsoleApp2
  8. 8 {
  9. 9     internal class Program
  10. 10     {
  11. 11         static void Main(string[] args)
  12. 12         {
  13. 13             Person person = new Person()
  14. 14             {
  15. 15                 Id = 1,
  16. 16                 Name = "公子小六",
  17. 17                 Birthday = DateTime.Now,
  18. 18             };
  19. 19             //bin格式序列化
  20. 20             var binHelper = new BinHelper();
  21. 21             string binPath = @"D:\serialize\person.bin";
  22. 22             binHelper.Serialize<Person>(person, binPath);
  23. 23
  24. 24             //xml格式序列化
  25. 25             var xmlHelper = new XmlHelper();
  26. 26             string xmlPath = @"D:\serialize\person.xml";
  27. 27             xmlHelper.Serialize<Person>(person, xmlPath);
  28. 28
  29. 29             //json格式序列化
  30. 30             var jsonHelper = new JsonHelper();  
  31. 31             string jsonPath = @"D:\serialize\person.json";
  32. 32             jsonHelper.Serialize<Person>(person, jsonPath);
  33. 33
  34. 34             //protobuf格式序列化
  35. 35             var protoHelper= new ProtobufHelper();
  36. 36             var protoPath = @"D:\serialize\person.proto";
  37. 37             protoHelper.Serialize<Person>(person, protoPath);
  38. 38         }
  39. 39     }
  40. 40 }
复制代码
反序列化,将本地文件反序列化成内存对象,如下所示:
  1. 1 using System;
  2. 2 using System.Collections.Generic;
  3. 3 using System.Linq;
  4. 4 using System.Text;
  5. 5 using System.Threading.Tasks;
  6. 6
  7. 7 namespace ConsoleApp2
  8. 8 {
  9. 9     internal class Program
  10. 10     {
  11. 11         static void Main(string[] args)
  12. 12         {
  13. 13             //bin格式反序列化
  14. 14             var binHelper = new BinHelper();
  15. 15             string binPath = @"D:\serialize\person.bin";
  16. 16             var p1 = binHelper.Deserialize<Person>(binPath);
  17. 17             //xml格式反序列化
  18. 18             var xmlHelper = new XmlHelper();
  19. 19             string xmlPath = @"D:\serialize\person.xml";
  20. 20             var p2 = xmlHelper.Deserialize<Person>(xmlPath);
  21. 21             //json格式反序列化
  22. 22             var jsonHelper = new JsonHelper();  
  23. 23             string jsonPath = @"D:\serialize\person.json";
  24. 24             var p3 = jsonHelper.Deserialize<Person>(jsonPath);
  25. 25             //protobuf格式反序列化
  26. 26             var protoHelper= new ProtobufHelper();
  27. 27             var protoPath = @"D:\serialize\person.proto";
  28. 28             var p4= protoHelper.Deserialize<Person>(protoPath);
  29. 29
  30. 30             Console.WriteLine($"p1:{p1}");
  31. 31             Console.WriteLine($"p2:{p2}");
  32. 32             Console.WriteLine($"p3:{p3}");
  33. 33             Console.WriteLine($"p4:{p4}");
  34. 34         }
  35. 35     }
  36. 36 }
  37. 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】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具