最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

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项目,在其他类型的项目中,也比较常见。具体场景如下所示:

  1. 将内存的对象序列化后保存在本地,上传到某些特定位置,如:共享目录,FTP,供第3方系统识别读取。
  2. 与第3方进行通信,对方只能接收二进制类型字节流数据,
  3. 保存Session,Cookie等场景
  4. 跨平台,跨语言交互等场景

常见序列化格式

常见的序列化数据格式有:

  1. 整体二进制,将实例对象整体序列化成二进制,
  2. xml格式,将实例对象序列化成XML数据格式,多用于WebService,
  3. json格式,将实例对象序列化成JSON文件格式,多用于WebAPI等Restful数据调用,
  4. 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     /// 10     /// 序列化帮助类接口11     /// 12     public interface ISerializeHelper13     {14         /// 15         /// 序列化16         /// 17         /// 18         /// 19         /// 序列化后保存路径20         void Serialize(T t, string path) where T : class;21 22         /// 23         /// 反序列化24         /// 25         /// 26         /// 反序列化文件路径27         /// 28         T Deserialize(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     /// 11     /// 个人信息12     /// 13     [ProtoContract]14     [Serializable]15     public class Person16     {17         /// 18         /// 唯一标识19         /// 20         [ProtoMember(1)]21         public int Id { get; set; }22 23         /// 24         /// 姓名25         /// 26         [ProtoMember(2)]27         public string Name { get; set; }28 29         /// 30         /// 生日31         /// 32         [ProtoMember(3)]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点需要注意:

  1. 进行整体二进制序列化,必须将类标记为Serializable,否则会抛异常。
  2. 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 ConsoleApp210 {11     internal class BinHelper : ISerializeHelper12     {13         public T Deserialize(string path) where T:class14         {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, string path) where T : class26         {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 ConsoleApp210 {11     public class XmlHelper : ISerializeHelper12     {13         public T Deserialize(string path) where T : class14         {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, string path) where T : class27         {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 ConsoleApp210 {11     internal class JsonHelper : ISerializeHelper12     {13         public T Deserialize(string path) where T : class14         {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, string path) where T : class26         {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 ConsoleApp211 {12     internal class ProtobufHelper : ISerializeHelper13     {14         public T Deserialize(string path) where T : class15         {16             string filePath = path;17             T t;18             using (FileStream fs = new FileStream(filePath, FileMode.Open))19             {20                 t = Serializer.Deserialize(fs);21             }22             return t;23         }24 25         public void Serialize(T t, string path) where T : class26         {27             string filePath = path;28             using (FileStream fs = new FileStream(filePath, FileMode.Create))29             {30                 Serializer.Serialize(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 Program10     {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, binPath);23 24             //xml格式序列化25             var xmlHelper = new XmlHelper();26             string xmlPath = @"D:\serialize\person.xml";27             xmlHelper.Serialize(person, xmlPath);28 29             //json格式序列化30             var jsonHelper = new JsonHelper();  31             string jsonPath = @"D:\serialize\person.json";32             jsonHelper.Serialize(person, jsonPath);33 34             //protobuf格式序列化35             var protoHelper= new ProtobufHelper();36             var protoPath = @"D:\serialize\person.proto";37             protoHelper.Serialize(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 Program10     {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(binPath);17             //xml格式反序列化18             var xmlHelper = new XmlHelper();19             string xmlPath = @"D:\serialize\person.xml";20             var p2 = xmlHelper.Deserialize(xmlPath);21             //json格式反序列化22             var jsonHelper = new JsonHelper();  23             string jsonPath = @"D:\serialize\person.json";24             var p3 = jsonHelper.Deserialize(jsonPath);25             //protobuf格式反序列化26             var protoHelper= new ProtobufHelper();27             var protoPath = @"D:\serialize\person.proto";28             var p4= protoHelper.Deserialize(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按不同格式序列化后的本地文件大小进行比较,具体如下:

  1. 整体二进制格式:person.bin 225字节
  2. XML格式:person.xml 242字节
  3. JSON格式:person.json 77字节
  4. Protobuf格式:person.proto 29字节

经过比较,Proto最小,XML最大,所以在对于大小要求比较严格的场景,可优先考虑Protobuf格式。

以上就是ASP.NET Core MVC 从入门到精通之序列化的全部内容。

关键词: