ASP.NET Core MVC 從入門到精通之序列化

来源:https://www.cnblogs.com/hsiang/archive/2023/05/07/17378782.html
-Advertisement-
Play Games

隨著技術的發展,ASP.NET Core MVC也推出了好長時間,經過不斷的版本更新迭代,已經越來越完善,本系列文章主要講解ASP.NET Core MVC開發B/S系統過程中所涉及到的相關內容,適用於初學者,在校畢業生,或其他想從事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. 序列化幫助類介面

 

為了統一調用方式,特定義序列化幫助類介面,不同實現方式,只需實現對應介面即可,介面定義如下:

 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 從入門到精通之序列化的全部內容。


作者:小六公子
出處:http://www.cnblogs.com/hsiang/
本文版權歸作者和博客園共有,寫文不易,支持原創,歡迎轉載【點贊】,轉載請保留此段聲明,且在文章頁面明顯位置給出原文連接,謝謝。
關註個人公眾號,定時同步更新技術及職場文章


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 說明 使用 VLD 記憶體泄漏檢測工具輔助開發時整理的學習筆記。本篇介紹 VLD 源碼的調試。同系列文章目錄可見 《記憶體泄漏檢測工具》目錄 1. VLD 庫源碼調試步驟 以 vld2.5.1 版本為例,下載源碼 後,源碼包中各文件的用途可看本人另一篇博客 【VLD】源碼文件概覽。使用 VLD 進行泄漏 ...
  • 在Ubuntu下,使用VS Code來編輯代碼或進行開發非常方便,下麵記錄一下如何配置gcc/g++編譯器和GDB調試工具。 準備工作: 1. 安裝VS Code,過程略。 2. 為VS Code安裝C/C++ Extension Pack 擴展組件,其他插件會附帶安裝 3. Ubuntu系統自帶g ...
  • 分享一份讀者面試美團的面經,比較有參考性,感興趣的可以看看~ 一面 消息隊列如何保證可靠性 消息隊列如何保證消息冪等性 消息隊列的優缺點 為什麼用b+樹 聚集索引和主鍵區別,其他引擎怎麼做的 平時資料庫編碼 explain參數 http報文參數有哪些嗎? 做題,鏈表奇偶有序輸出 二面 自我介紹 有哪 ...
  • 本文是使用ChatCPT生成的,最終的代碼使用起來沒問題。代碼是通過兩輪對話完善的,後面把對話合併後跑不出理想效果就沒嘗試了。 第一輪對話 請求 c++11實現一個線程安全的map,使用方法與std::map保持一致,實現[]運算符 回覆 以下是一個簡單的線程安全的map實現,可以使用[]運算符來訪 ...
  • 1.打開QtCreator進行如下選擇。(開軟去官網下載即可,註冊郵箱可以斷網跳過) 第一步: 選擇Application 第二步:這裡文件名稱和路徑都不要有中文 第三步:選擇編譯模式 點擊下一步 第四步:選擇 Widget點擊下一步 第五步:運行工程,判斷是否創建成功 課堂小記: 1.析構函數不能 ...
  • ResellerClub購買功能變數名稱 ResellerClub 是一個全球領先的功能變數名稱註冊和網站托管解決方案提供商,屬於 Endurance International Group(EIG)旗下的一家品牌。ResellerClub 通過其領先的平臺和定製解決方案,為全球數百萬個網站提供了強大的托管和功能變數名稱服 ...
  • FreeSSL申請免費證書 FreeSSL 是一個免費證書和 SSL 證書管理平臺。旨在為個人和小型企業提供免費 SSL 證書,以加強他們的網站和應用程式的安全性。與傳統的 SSL 證書頒發機構不同,FreeSSL 使用自動化過程生成 SSL 證書,並提供一個管理面板,讓用戶可以輕鬆管理他們的證書和 ...
  • AspNetCoreRateLimit應用於MVC項目求助 前言 之前發過一篇文章: .NET Core WebApi介面ip限流實踐 - 妙妙屋(zy) - 博客園 (cnblogs.com) 然後應用在前後端分離項目這個組件是非常好用的。但應用於不分離的項目,比如我的個人博客就有點麻煩。 就是我 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...