隨著技術(shù)的發(fā)展,ASP.NET Core MVC也推出了好長時間,經(jīng)過不斷的版本更新迭代,已經(jīng)越來越完善,本系列文章主要講解ASP.NET Core MVC開發(fā)B/S系統(tǒng)過程中所涉及到的相關(guān)內(nèi)容,適用于初學(xué)者,在校畢業(yè)生,或其他想從事ASP.NET Core MVC 系統(tǒng)開發(fā)的人員。 經(jīng)過前幾篇文章的講解,初步了解ASP.NET Core MVC項目創(chuàng)建,啟動運行,以及命名約定,創(chuàng)建控制器,視圖,模型,接收參數(shù),傳遞數(shù)據(jù)ViewData,ViewBag,路由,頁面布局,wwwroot和客戶端庫,Razor語法,EnityFrameworkCore與數(shù)據(jù)庫,HttpContext,Request,Response,Session等內(nèi)容,今天繼續(xù)講解ASP.NET Core MVC 中序列化等相關(guān)內(nèi)容,僅供學(xué)習(xí)分享使用。
?
什么是序列化和反序列化?
?
序列化是將對象狀態(tài)轉(zhuǎn)換為可保持或傳輸?shù)男问降倪^程。 序列化的補集是反序列化,后者將流轉(zhuǎn)換為對象。 這兩個過程一起保證能夠存儲和傳輸數(shù)據(jù)。
?
序列化應(yīng)用場景
?
在實際應(yīng)用中,序列化和反序列化,并不局限于ASP.NET Core MVC項目,在其他類型的項目中,也比較常見。具體場景如下所示:
- 將內(nèi)存的對象序列化后保存在本地,上傳到某些特定位置,如:共享目錄,F(xiàn)TP,供第3方系統(tǒng)識別讀取。
- 與第3方進行通信,對方只能接收二進制類型字節(jié)流數(shù)據(jù),
- 保存Session,Cookie等場景
- 跨平臺,跨語言交互等場景
?
常見序列化格式
?
常見的序列化數(shù)據(jù)格式有:
- 整體二進制,將實例對象整體序列化成二進制,
- xml格式,將實例對象序列化成XML數(shù)據(jù)格式,多用于WebService,
- json格式,將實例對象序列化成JSON文件格式,多用于WebAPI等Restful數(shù)據(jù)調(diào)用,
- Protobuf,即Protocol Buffers,是Google公司開發(fā)的一種跨語言和平臺的序列化數(shù)據(jù)結(jié)構(gòu)的方式,是一個靈活的、高效的用于序列化數(shù)據(jù)的協(xié)議。
?
序列化示例
?
在本示例中,為便于比較序列化后內(nèi)容大小,將序列化后內(nèi)容保存到本地文件,且實現(xiàn)了序列化和反序列化功能。
?
1. 安裝第三方庫
?
序列化JSON和Protobuf需要安裝第三方庫,可通過NuGet包管理器進行安裝,如下所示:
?
2. 序列化幫助類接口
?
為了統(tǒng)一調(diào)用方式,特定義序列化幫助類接口,不同實現(xiàn)方式,只需實現(xiàn)對應(yīng)接口即可,接口定義如下:
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
?
在本示例中,為了比較序列化格式的不同結(jié)果,定義一個測試類,如下所示:
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點需要注意:
- 進行整體二進制序列化,必須將類標記為Serializable,否則會拋異常。
- Protobuf序列化需要將類標記為ProtoContract,并將需要序列化的屬性標記為ProtoMember
?
4. 整體二進制
?
整體二進制是將實例對象整體序列化成二進制字節(jié)流,以及從二進制字節(jié)流反序列成實例對象,如下所示:
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是一種可擴展標記語言,多用于接口調(diào)用及數(shù)據(jù)傳輸,語言無關(guān),曾經(jīng)也是風(fēng)靡一時,是接口開發(fā)的首選。序列化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)是一種輕量級的數(shù)據(jù)交換格式,可使人們很容易地進行閱讀和編寫,同時也方便了機器進行解析和生成。JSON適用于進行數(shù)據(jù)交互的場景,如網(wǎng)站前臺與后臺之間的數(shù)據(jù)交互。JSON是比XML更簡單的一種數(shù)據(jù)交換格式,它采用完全獨立于編程語言的文本格式來存儲和表示數(shù)據(jù)。序列化JSON一般采用第3方庫Newtonsoft.Json來實現(xiàn),具體代碼如下所示:
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公司開發(fā)的一種跨語言和平臺的序列化數(shù)據(jù)結(jié)構(gòu)的方式,是一個靈活的、高效的用于序列化數(shù)據(jù)的協(xié)議。與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 }
反序列化,將本地文件反序列化成內(nèi)存對象,如下所示:
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按不同格式序列化后的本地文件大小進行比較,具體如下:
- 整體二進制格式:person.bin 225字節(jié)
- XML格式:person.xml 242字節(jié)
- JSON格式:person.json 77字節(jié)
- Protobuf格式:person.proto 29字節(jié)
經(jīng)過比較,Proto最小,XML最大,所以在對于大小要求比較嚴格的場景,可優(yōu)先考慮Protobuf格式。文章來源:http://www.zghlxwxcb.cn/news/detail-435931.html
以上就是ASP.NET Core MVC 從入門到精通之序列化的全部內(nèi)容。文章來源地址http://www.zghlxwxcb.cn/news/detail-435931.html
到了這里,關(guān)于ASP.NET Core MVC 從入門到精通之序列化的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!