詳解.NET Core 3.0 里新的JSON API
為什么需要新的 JSON API ?
JSON.NET 大家都用過,老版本的 ASP.NET Core 也依賴于 JSON.NET 。
然而這個(gè)依賴就會(huì)引起一些版本問題:例如 ASP .NET Core某個(gè)版本需要使用 JSON .NET v10 ,而另一個(gè)庫需要使用 JSON.NET v11 ;或者 JSON .NET 出現(xiàn)了一個(gè)新版本,而ASP .NET Core 還不能支持這個(gè)版本,而您卻想使用該版本。
System.Text.Json
隨著 NET Core 3.0 的出現(xiàn),出現(xiàn)了 System .Text.Json 命名空間和它下面一些用于處理 JSON 的類。
特點(diǎn)
這個(gè)內(nèi)置 JSON API 具有與生俱來的高性能、地分配的特點(diǎn):
JSON .NET 使用 .NET 里面的字符串作為基本數(shù)據(jù)類型,其實(shí)也就是 UTF16 ,而 .NET Core 中新的 JSON API 直接使用數(shù)據(jù)原始的 UTF8 格式。
新的 JSON API 基于 Span <byte> 這個(gè)數(shù)據(jù)類型來進(jìn)行操作 JSON 數(shù)據(jù),從而具有低分配的特點(diǎn),這就可以極大的改善吞吐量和內(nèi)存使用情況。
但是新的JSON API 的特性還不那么豐富,有一些 JSON .NET 具有的特性都還不支持。
例子
隨便找了一個(gè) JSON 示例文件:
針對(duì)這個(gè)文件,需要修改一下它的屬性:
Utf8JsonReader
先使用 Utf8JsonReader 來讀取JSON文件。
Utf8JsonReader 并不會(huì)讀取文件或者 stream ,它會(huì)讀取Span數(shù)據(jù)類型。
直接上代碼:
Main方法里面,我們使用 File .ReadAllBytes 從 sample .json 文件讀取數(shù)格式為 byte[] ,然后通過 AsSpan 這個(gè)擴(kuò)展方法將其轉(zhuǎn)化為 Span <byte> 數(shù)據(jù)類型,然后把它傳遞到 Utf8JsonReader 的構(gòu)造函數(shù)來創(chuàng)建一個(gè)JSON的 reader 。
接下來使用while循環(huán)對(duì)JSON數(shù)據(jù)的每個(gè) Token 進(jìn)行讀取,每次執(zhí)行 Read() 方法時(shí), reader 就會(huì)移動(dòng)到 JSON 數(shù)據(jù)里面的下一個(gè) Token 那里。
Token 分成幾種類型, GetToken Info 方法就是判斷一下 Token 的類型,并返回一些描述性信息,這里面應(yīng)該是包含了所有的類型。這里面使用到了C# 8 的 switch 表達(dá)式。
運(yùn)行程序
結(jié)果如下:
可以看到 sample.json 文件里面的每個(gè) Token 都被正確的顯示了。
Json Document 類
Json Document 是基于 Utf8JsonReader 構(gòu)建的 。 JsonDocument 可分析 JSON 數(shù)據(jù)并生成只讀文檔對(duì)象模型 (DOM) ,可對(duì)模型進(jìn)行查詢,以支持隨機(jī)訪問和枚舉。使用 JsonDocument 分析常規(guī) JSON 有效負(fù)載并訪問其所有成員比使用 Json.NET 快 2-3 倍,且為合理大?。? < 1 MB )的數(shù)據(jù)所分配的量非常少。
JsonDocument 可以處理 Span ,也可以處理 Stream 。
例子:
這里我通過 File .OpenRead 把 json 文件轉(zhuǎn)化為 stream 。然后使用 Json Document.Parse 方法把 stream 解析成 JSON 文檔對(duì)象模型。
注意,這里我使用了 C# 8 的 using var 語法,這個(gè)以后再說。
下面我們開始從這個(gè) JSON 文檔對(duì)象模型的根節(jié)點(diǎn)開始遍歷,也就是 RootElement :
然后通過 root 這個(gè) JsonElement 類型的對(duì)象的 GetProperty 方法來獲得相應(yīng)的屬性,而且這個(gè)方法可以連串使用:
最后一行使用 GetString 方法來獲得該屬性的字符串值。
然后我們可以寫一個(gè)遞歸調(diào)用的方法來遍歷整個(gè)模型的每個(gè)屬性:
這個(gè)方法接受 JsonElement 類型的對(duì)象,然后對(duì)該元素的屬性進(jìn)行循環(huán)。
如果當(dāng)前屬性是另一個(gè)對(duì)象,那么就繼續(xù)遞歸調(diào)用這個(gè)方法;
否則就輸出原始的文本。
最后調(diào)用該方法:
輸出結(jié)果為:
與json文件的內(nèi)容匹配。
Utf8JsonWriter 類
下面研究一下如何寫入json文件。這里需要使用Utf 8JsonWriter 類。
直接看代碼:
這個(gè)類需要傳遞的參數(shù)類型是 Stream 或者Buffer,也就是向 Stream 或 Buffer 里面寫入數(shù)據(jù)。
那么就提供一個(gè) buffer :
下面單獨(dú)寫一個(gè)方法,來生成json數(shù)據(jù):
參數(shù)類型是Utf 8JsonWriter 。通過智能提示可以看到它提供了很多用于寫入不同類型數(shù)據(jù)的方法。
寫 JSON 對(duì)象
現(xiàn)在我想寫一個(gè)json對(duì)象,那么就從Write StartObject () 開始,然后以WriteEnd Object() 結(jié)束 :
這樣的話,實(shí)際上我已經(jīng)擁有了一個(gè)合法的json文檔。
寫屬性和值
可以分開寫屬性和值:
也可以同時(shí)把屬性和值寫出來:
顯示 JSON 數(shù)據(jù)
我先寫這些內(nèi)容,然后在Main方法里面調(diào)用一下:
首先需要告訴writer把它的內(nèi)容flush給buffer,使用這個(gè)buffer我們可以獲得 writer 的輸出,這樣的話就會(huì)得到一個(gè)byte數(shù)組,然后把這個(gè) byte 數(shù)組轉(zhuǎn)化為字符串,這樣就可以在控制臺(tái)顯示它了:
運(yùn)行一下看看效果:
沒啥太大的問題,就是格式不好看。
對(duì)輸出進(jìn)行格式化
.NET Core 提供了一個(gè) JsonWrite r Options 類,它可以對(duì)Writer進(jìn)行一些設(shè)置。
這里對(duì)輸出進(jìn)行了縮進(jìn),最后把這個(gè)options傳遞給Utf 8JsonWriter 的構(gòu)造函數(shù)即可。
再次運(yùn)行:
現(xiàn)在好看多了。
JsonSerializer
前面幾節(jié)的內(nèi)容可能稍微有點(diǎn)底層,我們大部分時(shí)候可能只需要對(duì) C# 的類進(jìn)行串行化或者將 JSON 數(shù)據(jù)反串行化成 C# 類,在 .NET Core 3.0 里面,我們可以使用 JsonSerializer 這個(gè)類來做這些事情。
例子:
還是使用之前用到的 json 數(shù)據(jù):
然后我們需要建建立兩個(gè)類,對(duì)應(yīng)這個(gè)文件:
反串行化
可以使用Json Serializer 類的 Deserialize() 方法對(duì) json 數(shù)據(jù)反串行化。這個(gè)方法支持三種類型的輸入?yún)?shù),分別是:
- JSON數(shù)據(jù)的字符串
- Utf 8JsonReader
- Read OnlySpan<byte> ,它里面包含 JSON 數(shù)據(jù)
為了簡單一點(diǎn),我直接把json文件讀取成字符串,然后傳給 Deserialize 方法:
然后我試圖打印出反串行化之后的一些屬性數(shù)據(jù)。但是這不會(huì)成功。因?yàn)镴SON文件里面數(shù)據(jù)的大小寫命名規(guī)范使用的是 camel casing (簡單理解為首字母是小寫的),而默認(rèn)情況下 Deserializer 會(huì)尋找 Pascal casing 這種規(guī)范(簡單理解為每個(gè)單詞的首字母都是大寫的)的屬性名。
格式化
為解決這個(gè)問題,就需要使用 JsonSerializerOptions 類:
建立該類的一個(gè)實(shí)例,設(shè)置 Property NamingPolicy 為 CamelCase ,然后把這個(gè)實(shí)例傳遞給 Deserialize 方法的第二個(gè)參數(shù)。
運(yùn)行看結(jié)果 :
這次就沒有問題了。
串行化
Json Serializer 也支持串行化,也就是把C#數(shù)據(jù)轉(zhuǎn)化為 JSON 數(shù)據(jù):
這里使用了相同的 options 。
運(yùn)行結(jié)果:
如果想讓輸出結(jié)果更好看一些,可以在 JsonSerializerOptions 里面進(jìn)行相應(yīng)的設(shè)置:
這次輸出結(jié)果為:
總結(jié)
總結(jié)一下 .NET Core 3.0 新的JSON API :
- Utf 8JsonReader - 讀操作,快速,低級(jí)
- Utf 8JsonWriter - 寫操作,快速,低級(jí)
- JsonDocument - 基于DOM,快速
- Json Seriliazer - 串行化 / 反串行化,快速
另外 JSON .NET 仍然被支持。
到此這篇關(guān)于詳解.NET Core 3.0 里新的JSON API的文章就介紹到這了,更多相關(guān).NET Core 3.0 JSON 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- .Net Core讀取Json配置文件的實(shí)現(xiàn)示例
- 淺析.Net Core中Json配置的自動(dòng)更新
- .net core如何在網(wǎng)絡(luò)高并發(fā)下提高JSON的處理效率詳解
- .NET Core簡單讀取json配置文件
- .NetCore獲取Json和Xml格式的配置信息
- Asp.NetCore1.1版本去掉project.json后如何打包生成跨平臺(tái)包
- ASP.NET Core Project.json文件(5)
- ASP.NET core Web中使用appsettings.json配置文件的方法
- 詳解ASP.NET Core 在 JSON 文件中配置依賴注入
相關(guān)文章
asp.net使用ODP即oracle連接方式的的防注入登錄驗(yàn)證程序
這篇文章主要介紹了asp.net使用ODP即oracle連接方式的的防注入登錄驗(yàn)證程序,需要的朋友可以參考下2014-05-05ASP.NET中使用Application對(duì)象實(shí)現(xiàn)簡單在線人數(shù)統(tǒng)計(jì)功能
這篇文章主要介紹了ASP.NET中使用Application對(duì)象實(shí)現(xiàn)簡單在線人數(shù)統(tǒng)計(jì)功能,本文給出實(shí)現(xiàn)步驟和相應(yīng)代碼實(shí)例,需要的朋友可以參考下2015-06-06ASP.NET Core Authentication認(rèn)證實(shí)現(xiàn)方法
這篇文章主要介紹了ASP.NET Core Authentication認(rèn)證實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08asp.net實(shí)現(xiàn)中英文多域名檢測的方法
這篇文章主要介紹了asp.net實(shí)現(xiàn)中英文多域名檢測的方法,涉及asp.net針對(duì)URL中域名的解析及字符串操作相關(guān)技巧,需要的朋友可以參考下2016-08-08asp.net 頁面間傳值與跳轉(zhuǎn)的區(qū)別
通過Server.Transfer("b.aspx") 與Response.Redirect("b.aspx")的區(qū)別2010-04-04一步步打造簡單的MVC電商網(wǎng)站BooksStore(1)
這篇文章主要和大家一起一步步打造一個(gè)簡單的MVC電商網(wǎng)站,MVC電商網(wǎng)站BooksStore第一篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04