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

news2024/11/24 5:02:11

随着技术的发展,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. 序列化帮助类接口

为了统一调用方式,特定义序列化帮助类接口,不同实现方式,只需实现对应接口即可,接口定义如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    /// <summary>
    /// 序列化帮助类接口
    /// </summary>
    public interface ISerializeHelper
    {
        /// <summary>
        /// 序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <param name="path">序列化后保存路径</param>
        void Serialize<T>(T t, string path) where T : class;

        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path">反序列化文件路径</param>
        /// <returns></returns>
        T Deserialize<T>(string path) where T : class;
    }
}

3. 定义序列化模型类Person

在本示例中,为了比较序列化格式的不同结果,定义一个测试类,如下所示:

using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    /// <summary>
    /// 个人信息
    /// </summary>
    [ProtoContract]
    [Serializable]
    public class Person
    {
        /// <summary>
        /// 唯一标识
        /// </summary>
        [ProtoMember(1)]
        public int Id { get; set; }

        /// <summary>
        /// 姓名
        /// </summary>
        [ProtoMember(2)]
        public string Name { get; set; }

        /// <summary>
        /// 生日
        /// </summary>
        [ProtoMember(3)]
        public DateTime Birthday { get; set; }

        public override string ToString()
        {
            return $"Id={Id},Name={Name},Birthday={Birthday.ToString("yyyy-MM-dd HH:mm:ss.fff")}";
        }

    }
}

注意:定义Person时,有以下2点需要注意:

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

4. 整体二进制

整体二进制是将实例对象整体序列化成二进制字节流,以及从二进制字节流反序列成实例对象,如下所示:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    internal class BinHelper : ISerializeHelper
    {
        public T Deserialize<T>(string path) where T:class
        {
            string filePath = path;
            T t;
            using (FileStream fs = new FileStream(filePath, FileMode.Open))
            {
                BinaryFormatter bf = new BinaryFormatter();
                t = bf.Deserialize(fs) as T;
            }
            return t;
        }

        public void Serialize<T>(T t, string path) where T : class
        {
            string filePath = path;
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(fs, t);
            }
        }
    }
}

5. XML格式

XML是一种可扩展标记语言,多用于接口调用及数据传输,语言无关,曾经也是风靡一时,是接口开发的首选。序列化XML代码如下所示:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace ConsoleApp2
{
    public class XmlHelper : ISerializeHelper
    {
        public T Deserialize<T>(string path) where T : class
        {
            string filePath = path;
            T t;
            using (FileStream fs = new FileStream(filePath, FileMode.Open))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Person));
                object obj = serializer.Deserialize(fs);
                t = obj as T;
            }
            return t;
        }

        public void Serialize<T>(T t, string path) where T : class
        {
            string filePath = path;
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Person));
                serializer.Serialize(fs, t);
            }
        }
    }
}

6. JSON格式

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,可使人们很容易地进行阅读和编写,同时也方便了机器进行解析和生成。JSON适用于进行数据交互的场景,如网站前台与后台之间的数据交互。JSON是比XML更简单的一种数据交换格式,它采用完全独立于编程语言的文本格式来存储和表示数据。序列化JSON一般采用第3方库Newtonsoft.Json来实现,具体代码如下所示:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    internal class JsonHelper : ISerializeHelper
    {
        public T Deserialize<T>(string path) where T : class
        {
            T t;
            using (StreamReader file = File.OpenText(path))
            {
                JsonSerializer serializer = new JsonSerializer();
                t = (T)serializer.Deserialize(file, typeof(T));

            }
            return t;
        }

        public void Serialize<T>(T t, string path) where T : class
        {
            using (StreamWriter file = File.CreateText(path))
            {
                JsonSerializer serializer = new JsonSerializer();
                serializer.Serialize(file, t);
            }
        }
    }
}

7. Protobuf格式

Protobuf即Protocol Buffers,是Google公司开发的一种跨语言和平台的序列化数据结构的方式,是一个灵活的、高效的用于序列化数据的协议。与XML和JSON格式相比,protobuf更小、更快、更便捷。序列化Protobuf格式代码如下:

using ProtoBuf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    internal class ProtobufHelper : ISerializeHelper
    {
        public T Deserialize<T>(string path) where T : class
        {
            string filePath = path;
            T t;
            using (FileStream fs = new FileStream(filePath, FileMode.Open))
            {
                t = Serializer.Deserialize<T>(fs);
            }
            return t;
        }

        public void Serialize<T>(T t, string path) where T : class
        {
            string filePath = path;
            using (FileStream fs = new FileStream(filePath, FileMode.Create))
            {
                Serializer.Serialize<T>(fs, t);
            }
        }
    }
}

8. 实例测试

对同一个对象,进行不同格式的序列化,如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Person person = new Person()
            {
                Id = 1,
                Name = "公子小六",
                Birthday = DateTime.Now,
            };
            //bin格式序列化
            var binHelper = new BinHelper();
            string binPath = @"D:\serialize\person.bin";
            binHelper.Serialize<Person>(person, binPath);

            //xml格式序列化
            var xmlHelper = new XmlHelper();
            string xmlPath = @"D:\serialize\person.xml";
            xmlHelper.Serialize<Person>(person, xmlPath);

            //json格式序列化
            var jsonHelper = new JsonHelper();
            string jsonPath = @"D:\serialize\person.json";
            jsonHelper.Serialize<Person>(person, jsonPath);

            //protobuf格式序列化
            var protoHelper= new ProtobufHelper();
            var protoPath = @"D:\serialize\person.proto";
            protoHelper.Serialize<Person>(person, protoPath);
        }
    }
}

反序列化,将本地文件反序列化成内存对象,如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //bin格式反序列化
            var binHelper = new BinHelper();
            string binPath = @"D:\serialize\person.bin";
            var p1 = binHelper.Deserialize<Person>(binPath);
            //xml格式反序列化
            var xmlHelper = new XmlHelper();
            string xmlPath = @"D:\serialize\person.xml";
            var p2 = xmlHelper.Deserialize<Person>(xmlPath);
            //json格式反序列化
            var jsonHelper = new JsonHelper();
            string jsonPath = @"D:\serialize\person.json";
            var p3 = jsonHelper.Deserialize<Person>(jsonPath);
            //protobuf格式反序列化
            var protoHelper= new ProtobufHelper();
            var protoPath = @"D:\serialize\person.proto";
            var p4= protoHelper.Deserialize<Person>(protoPath);

            Console.WriteLine($"p1:{p1}");
            Console.WriteLine($"p2:{p2}");
            Console.WriteLine($"p3:{p3}");
            Console.WriteLine($"p4:{p4}");
        }
    }
}

序列化大小比较

序列化后保存到本地的文件,如下所示:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/499895.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springboot +Flowable,任务认领和回退(三)

一.简介 有的时候&#xff0c;一个任务节点会存在多个候选人&#xff0c;例如&#xff1a;张三提交一个任务&#xff0c;这个任务即可以由李四处理&#xff0c;又可以由王五处理&#xff0c;那么针对这种多个任务候选人的情况&#xff0c;该如何处理&#xff1f; 二.绘制流程…

并发编程05:Java内存模型之JMM

文章目录 5.1 先从大场面试开始5.2 计算机硬件存储体系5.3 Java内存模型Java Memory Model5.4 JMM规范下三大特性5.5 JMM规范下多线程对变量的读写过程5.6 JMM规范下多线程先行发生原则之happens-before5.6.1 x,y案例说明5.6.2 先行并发原则说明5.6.3 happens-before总原则5.6.…

【面试题】面试官:说说你对MySQL的了解

文章目录 基础篇非关系型数据库和关系型数据库的区别&#xff1f;MySQL 数据库两种存储引擎的区别? 索引篇为什么索引能提高查询速度?聚集索引和非聚集索引的区别&#xff1f;非聚集索引一定回表查询吗?索引这么多优点&#xff0c;为什么不对表中的每一个列创建一个索引呢&a…

八岁都能懂:BFS判断一个图是二分图

目录 1 什么是二分图2 进入情境3 代码实现4 BFS是什么&#xff1f; 1 什么是二分图 一个图用两种颜色涂&#xff08;橙黄和橘绿&#xff09;&#xff0c;相邻节点不能同色&#xff0c;如下图&#xff0c;4与5相邻且同色&#xff0c;所以不是二分图。 2 进入情境 第一版&#xf…

微服务高频面试题

1、Spring Cloud 5大组件有哪些&#xff1f; 早期我们一般认为的Spring Cloud五大组件是 Eureka : 注册中心Ribbon : 负载均衡Feign : 远程调用Hystrix : 服务熔断Zuul/Gateway : 网关 随着SpringCloudAlibba在国内兴起 , 我们项目中使用了一些阿里巴巴的组件 注册中心/配置…

【论文】SimCLS:摘要总结的对比学习(2)

SimCLS:摘要总结的对比学习(1&#xff09; 写在最前面2 抽象总结的对比学习框架 写在最前面 SimCLS: A Simple Framework for Contrastive Learning of Abstractive Summarization&#xff08;2021ACL会议&#xff09; https://arxiv.org/abs/2106.01890 论文&#xff1a;htt…

HTTP第四讲——域名和DNS

IP 协议的职责是“网际互连”&#xff0c;它在 MAC 层之上&#xff0c;使用 IP 地址把 MAC 编号转换成了四位数字&#xff0c;这就对物理网卡的 MAC 地址做了一层抽象&#xff0c;发展出了许多的“新玩法”。 例如&#xff0c;分为 A、B、C、D、E 五种类型&#xff0c;公有地址…

[GFCTF 2021] day2

Baby_Web 查看源码发现 <!--源码藏在上层目录xxx.php.txt里面&#xff0c;但你怎么才能看到它呢?--> 然后抓包看中间件&#xff0c;Apache/2.4.49 (Unix) 存在目录穿越漏洞 curl http://node4.anna.nssctf.cn:28805/cgi-bin/.%2e/.%2e/.%2e/.%2e/var/www/index …

快速上手分布式异步任务框架Celery

一、Celery架构介绍 Celery&#xff1a;芹菜&#xff1f;&#xff08;跟翻译没有任何关系&#xff09;&#xff0c;分布式异步任务框架&#xff08;跟其他web框架无关&#xff09; Celery is a project with minimal funding, so we don’t support Microsoft Windows. Please…

【嵌入式系统】课程复习资料整理

【嵌入式系统】课程复习资料整理 一、绪论 1.定义 从技术的角度定义&#xff1a;以应用为中心、以计算机技术为基础、软件硬件可裁剪、对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。从系统的角度定义&#xff1a;嵌入式系统是设计完成复杂功能的硬件和软件&a…

Android多模块开发

Android多模块开发 1. 建立项目和多个模块 ​ app为主模块 ​ app-setting为功能模块&#xff0c;可作为独立模块运行&#xff0c;也可作为其他模块的资源模块 ​ app-video为功能模块 2. 建立公共环境文件(env.gradle)并在各模块配置 Step1&#xff1a; 建立在根目录下建…

第31步 机器学习分类实战:多轮建模

开始填坑之旅。 首先&#xff0c;之前提过&#xff0c;random_state这个参数&#xff0c;它的功能是确保每次随机抽样所得到的数据都是一样的&#xff0c;有利于数据的复现。比如&#xff0c;我们这十个ML模型&#xff0c;用的参数都是random_state666&#xff0c;这样作比较才…

【写一个hello的html页面,将页面放到服务器,通过浏览器访问页面,这个过程是怎么实现的?】第一个 servlet 程序

第一个 servlet 程序 第一个 servlet 程序1. 创建项目创建好后的 默认目录 解析 2. 引入依赖为什么要引入依赖&#xff1f; 3. 创建目录结构1、在 main 目录下创建一个 webapp 目录2、在 webapp 下创建一个 WEB-INF 目录3、在 WEB-INF 目录下创建一个 web.xml 文件4、web.xml 需…

章节3:02-Apache Commons Collections反序列化漏洞

章节3&#xff1a;02-Apache Commons Collections反序列化漏洞 02-Apache Commons Collections反序列化漏洞 漏洞爆出 2015.01.28 Gabriel Lawrence和Chris Frohoff https://speakerdeck.com/frohoff/appseccali-2015-marshalling-pickles-how-deserializing-objects-can-r…

《Java虚拟机学习》 asmtools 字节码汇编器使用 与 JVM识别方法重载 的思考

1.asmtools下载 链接&#xff1a;https://pan.baidu.com/s/1R3nAaUbN1Dkf6UKkdEMSEA?pwdk8l8 提取码&#xff1a;k8l8 2.结合方法重载实验的使用 总所周知&#xff0c;方法重载跟方法名无关&#xff0c;但对于JVM而言&#xff0c;区别方法主要通过 类名&#xff0c;方法名&…

java spring MVC REST风格概念叙述

REST属于spring MVC中的一个知识点 REST是三个单词的缩写 即 Representational State Transfer 意思为 表现形式状态转换 老实说 不用尝试字面上理解 因为字面意思 确实是比较抽象 其实 意思就是 访问网络资源的格式 转换 下图 对比了 传统风格和REST风格 请求路径的差别 RES…

【英语】大学英语CET考试,阅读部分2(长篇阅读,选词填空,综合演练)

文章目录 1、长篇阅读&#xff08;连连看&#xff0c;要会做&#xff09;1.1 解题技巧&#xff08;定位词扫读&#xff0c;看到大于看懂&#xff0c;一题带练&#xff09;1.2 做题方法复习总结1.3 题目练习&#xff08;2篇文章&#xff09; 2、选词填空&#xff08;只有5分&…

opencv_c++学习(五)

Mat类数值存储方式 上图为opencv中三通道数据的存储方式&#xff0c;反映到图像上则为空间维度为3*3&#xff0c;通道为3的图像。 Mat类的属性 Mat类的属性如上&#xff0c;在这里我们解释一下step。step是行列数与数据类型的字节数相乘的数据。 Mat类元素读取 在Mat中&…

云原生: istio+dapr构建多运行时服务网格...  多运行时是一个非常新的概念。在

2020 年&#xff0c;Bilgin Ibryam 提出了 Multi-Runtime&#xff08;多运行时&#xff09;的理念&#xff0c;对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华。那到底什么是多运行时呢&#xff1f;首先还是得从分布式应用的四大类基本需求讲起。简单来讲任何分布…

【力扣周赛】第344场周赛

【力扣周赛】第344场周赛 6416&#xff1a;找出不同元素数目差数组题目描述解题思路 6417&#xff1a;频率跟踪器题目描述解题思路 6418&#xff1a;有相同颜色的相邻元素数目题目描述解题思路 6419&#xff1a;使二叉树所有路径值相等的最小代价题目描述解题思路 6416&#xf…