随着技术的发展,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项目,在其他类型的项目中,也比较常见。具体场景如下所示:
常见的序列化数据格式有:
在本示例中,为便于比较序列化后内容大小,将序列化后内容保存到本地文件,且实现了序列化和反序列化功能。
序列化JSON和Protobuf需要安装第三方库,可通过NuGet包管理器进行安装,如下所示:
为了统一调用方式,特定义序列化帮助类接口,不同实现方式,只需实现对应接口即可,接口定义如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
///
/// 序列化帮助类接口
///
public interface ISerializeHelper
{
///
/// 序列化
///
///
///
/// 序列化后保存路径
void Serialize(T t, string path) where T : class;
///
/// 反序列化
///
///
/// 反序列化文件路径
///
T Deserialize(string path) where T : class;
}
}
在本示例中,为了比较序列化格式的不同结果,定义一个测试类,如下所示:
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
///
/// 个人信息
///
[ProtoContract]
[Serializable]
public class Person
{
///
/// 唯一标识
///
[ProtoMember(1)]
public int Id { get; set; }
///
/// 姓名
///
[ProtoMember(2)]
public string Name { get; set; }
///
/// 生日
///
[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点需要注意:
整体二进制是将实例对象整体序列化成二进制字节流,以及从二进制字节流反序列成实例对象,如下所示:
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(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, string path) where T : class
{
string filePath = path;
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, t);
}
}
}
}
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(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, 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);
}
}
}
}
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(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, string path) where T : class
{
using (StreamWriter file = File.CreateText(path))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, t);
}
}
}
}
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(string path) where T : class
{
string filePath = path;
T t;
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
t = Serializer.Deserialize(fs);
}
return t;
}
public void Serialize(T t, string path) where T : class
{
string filePath = path;
using (FileStream fs = new FileStream(filePath, FileMode.Create))
{
Serializer.Serialize(fs, t);
}
}
}
}
对同一个对象,进行不同格式的序列化,如下所示:
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, binPath);
//xml格式序列化
var xmlHelper = new XmlHelper();
string xmlPath = @"D:\serialize\person.xml";
xmlHelper.Serialize(person, xmlPath);
//json格式序列化
var jsonHelper = new JsonHelper();
string jsonPath = @"D:\serialize\person.json";
jsonHelper.Serialize(person, jsonPath);
//protobuf格式序列化
var protoHelper= new ProtobufHelper();
var protoPath = @"D:\serialize\person.proto";
protoHelper.Serialize(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(binPath);
//xml格式反序列化
var xmlHelper = new XmlHelper();
string xmlPath = @"D:\serialize\person.xml";
var p2 = xmlHelper.Deserialize(xmlPath);
//json格式反序列化
var jsonHelper = new JsonHelper();
string jsonPath = @"D:\serialize\person.json";
var p3 = jsonHelper.Deserialize(jsonPath);
//protobuf格式反序列化
var protoHelper= new ProtobufHelper();
var protoPath = @"D:\serialize\person.proto";
var p4= protoHelper.Deserialize(protoPath);
Console.WriteLine($"p1:{p1}");
Console.WriteLine($"p2:{p2}");
Console.WriteLine($"p3:{p3}");
Console.WriteLine($"p4:{p4}");
}
}
}
序列化后保存到本地的文件,如下所示:
对Person按不同格式序列化后的本地文件大小进行比较,具体如下:
经过比较,Proto最小,XML最大,所以在对于大小要求比较严格的场景,可优先考虑Protobuf格式。
以上就是ASP.NET Core MVC 从入门到精通之序列化的全部内容。