首页 > 编程语言 >ASP.NET Core MVC 从入门到精通之序列化

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

时间:2023-05-07 22:48:10浏览次数:45  
标签:Core ASP string 格式 System new using 序列化

随着技术的发展,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     /// <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     [ProtoContract]
14     [Serializable]
15     public class Person
16     {
17         /// <summary>
18         /// 唯一标识
19         /// </summary>
20         [ProtoMember(1)]
21         public int Id { get; set; }
22 
23         /// <summary>
24         /// 姓名
25         /// </summary>
26         [ProtoMember(2)]
27         public string Name { get; set; }
28 
29         /// <summary>
30         /// 生日
31         /// </summary>
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 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按不同格式序列化后的本地文件大小进行比较,具体如下:

  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 从入门到精通之序列化的全部内容。

标签:Core,ASP,string,格式,System,new,using,序列化
From: https://www.cnblogs.com/hsiang/p/17378782.html

相关文章

  • 基于aspectjwear方式开启aop
    今天刷到b站视频,看到aop织入,发现有点忘了。pom导入aspectjwear依赖,配置spring-aop.xml后引入contextaop context扫描包aspect开启aop自动识别。在切面类方法中配置切入点,测试发生以下错误。Causedby:org.springframework.beans.factory.BeanNotOfRequiredTypeException:Be......
  • Json数据的序列化与反序列化的三种常用方法介绍
    以下内容是本作者从官网中看相应的教程后所做的demo,其体现了作者对相关知识点的个人理解。。作者才疏学浅,难免会有理解不到位的地方。。还请各位读者批判性对待。。。    本文主要介绍在Json数据的序列化与反序列化的过程中我经常用到的三种工具的基本使用方法,及其他们之间......
  • Raspberry Pi & 0.96 inch OLED display All In One
    RaspberryPi&0.96inchOLEDdisplayAllInOneI2CGPIOPythondemos(......
  • js基础---对象的序列化(JSON)与map
    序列化概念json工具类就是那个转换字符串的方法调用json静态方法,不需要new。注意事项将对象转换为json后再转换为对象,相当于做了一次深复制。当对象的字符串key属性满足不了需求时,可用map的对象属性作为keymap属性和方法map与数组之间的转换......
  • abp(net core)+easyui+efcore实现仓储管理系统——供应商管理升级之下(六十四)
    abp(netcore)+easyui+efcore实现仓储管理系统目录abp(netcore)+easyui+efcore实现仓储管理系统——ABP总体介绍(一)abp(netcore)+easyui+efcore实现仓储管理系统——解决方案介绍(二)abp(netcore)+easyui+efcore实现仓储管理系统——领域层创建实体(三) abp(netcore)+eas......
  • FuzzyScore
    模糊分数implementation'org.apache.commons:commons-text:1.10.0'AmatchingalgorithmthatissimilartothesearchingalgorithmsimplementedineditorssuchasSublimeText,TextMate,Atomandothers.Onepointisgivenforeverymatchedcharacte......
  • java类序列化和反序列化
    参考:https://zhuanlan.zhihu.com/p/144535172?utm_id=0https://blog.csdn.net/qq_42617455/article/details/1096223901、问题解答(1)序列化和反序列化都需要哪些操作对象要实现java.io.Serializable接口增加序列化ID(privatestaticfinallongserialVersionUID)转化成便于传......
  • django内置序列化组件(drf前身)
    目录一、django内置序列化组件(drf前身)一、django内置序列化组件(drf前身)一、django内置序列化组件(drf前身)这里的内置序列化组件,其实就是实现将后端数据,存放到字典中或是存放到列表中有序输出。这里是我们用JsonResponse模块自己实现的代码'''前后端分离的项目视图函数......
  • Net Core Web Api 配置Swagger
    一、创建NETCoreAPI项目NETCore版本:NETCore2.21.创建coreweb应用程序2.选择API3.下图为生成后的项目二、安装Swagger1.打开NuGet包管理器2.搜索Swashbuckle.AspNetCore安装在项目上3.点击我接受三、配置Swagger对于ConfigureServices和Configure的配置点击可参考1.ConfigureS......
  • kubernetes域名解析服务CoreDNS
    k8sdns组件历史简介kubernetes的DNS组件历史有三个,分别是skydns、kube-dns和coredns;在k8s1.3版本之前使用的是skydns,之后的版本到1.17及之间的版本都是使用的kube-dns,1.18开始至今主要使用coredns;这些dns组件在k8s当中,主要作用就是解析k8s中servicename所对应的IP地......