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

简介: 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. 序列化帮助类接口

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

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

相关文章
|
22天前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
39 5
|
2月前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
46 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
30天前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
27 3
|
7天前
|
开发框架 算法 中间件
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
25 0
|
2月前
|
程序员 C# 图形学
全面的C#/.NET自学入门指南
全面的C#/.NET自学入门指南
|
5月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
2月前
|
JSON 数据格式 索引
Python中序列化/反序列化JSON格式的数据
【11月更文挑战第4天】本文介绍了 Python 中使用 `json` 模块进行序列化和反序列化的操作。序列化是指将 Python 对象(如字典、列表)转换为 JSON 字符串,主要使用 `json.dumps` 方法。示例包括基本的字典和列表序列化,以及自定义类的序列化。反序列化则是将 JSON 字符串转换回 Python 对象,使用 `json.loads` 方法。文中还提供了具体的代码示例,展示了如何处理不同类型的 Python 对象。
|
2月前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。
|
3月前
|
存储 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第9天】在Java的世界里,对象序列化是连接数据持久化与网络通信的桥梁。本文将深入探讨Java对象序列化的机制、实践方法及反序列化过程,通过代码示例揭示其背后的原理。从基础概念到高级应用,我们将一步步揭开序列化技术的神秘面纱,让读者能够掌握这一强大工具,以应对数据存储和传输的挑战。
|
3月前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第3天】在Java编程的世界里,对象序列化与反序列化是实现数据持久化和网络传输的关键技术。本文将深入探讨Java序列化的原理、应用场景以及如何通过代码示例实现对象的序列化与反序列化过程。从基础概念到实践操作,我们将一步步揭示这一技术的魅力所在。

相关实验场景

更多