.NET Core 3.0 System.Text.Json 和 Newtonsoft.Json 行为不一致问题及解决办法
行為不一致
.NET Core 3.0 新出了個內置的 JSON 庫, 全名叫做尼古拉斯?System.Text.Json?- 性能更高占用內存更少這都不是事...
對我來說, 很多或大或小的項目能少個第三方依賴項, 還能規避多個依賴項的依賴 Newtonsoft.Json 版本不一致的問題, 是件極美的事情.
但是, 結果總不是不如預期那么簡單和美好, 簡單測試了下, 有一些跟?Newtonsoft.Json?行為不一致的地方, 代碼如下:
using Microsoft.VisualStudio.TestTools.UnitTesting;namespace UnitTestProject3 {[TestClass]public class TestJsonDiff{[TestMethod][Description(description: "測試數字序列化")]public void TestNumber(){object jsonObject = new { number = 123.456 };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject);Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "測試數字序列化失敗");}[TestMethod][Description(description: "測試英文序列化")]public void TestEnglish(){object jsonObject = new { english = "bla bla" };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject);Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "測試英文序列化失敗");}[TestMethod][Description(description: "測試中文序列化")]public void TestChinese(){object jsonObject = new { chinese = "灰長標準的布咚發" };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject);Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "測試中文序列化失敗");}[TestMethod][Description(description: "測試英文符號")]public void TestEnglishSymbol(){object jsonObject = new { symbol = @"~`!@#$%^&*()_-+={}[]:;'<>,.?/ " };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject);Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "測試英文符號失敗");}[TestMethod][Description(description: "測試中文符號")]public void TestChineseSymbol(){object jsonObject = new { chinese_symbol = @"~·@#¥%……&*()—-+={}【】;:“”‘’《》,。?、" };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject);Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "測試中文符號失敗");}} }先來看看總體的測試結果:
這是 VS 顯示的結果
這是執行?dotnet test?命令行顯示的結果
這個時候需要配個圖
那么問題來了,?國慶去哪玩比較好呢, 我是誰? 這是哪? 發生了什么?
解決辦法
解決中文會被 Unicode 編碼的問題
這個問題是在博客園里找到的一種答案:?.NET Core 3.0 中使用 System.Text.Json 序列化中文時的編碼問題
[TestMethod] [Description(description: "測試中文序列化")] public void TestChinese() {object jsonObject = new { chinese = "灰長標準的布咚發" };string aJsonString = Newtonsoft.Json.JsonConvert.SerializeObject(value: jsonObject);string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject,options: new System.Text.Json.JsonSerializerOptions{Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(allowedRanges: UnicodeRanges.All)});Assert.AreEqual(expected: aJsonString, actual: bJsonString, message: "測試中文序列化失敗"); }關鍵在于序列化配置加了一句
new System.Text.Json.JsonSerializerOptions {Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(allowedRanges: UnicodeRanges.All) }但是一些符號被轉義的問題還是不管用, 尋思了一上午暫時沒找到答案...
至于什么時候修復此類問題,
我去源碼?corefx?溜個一圈, 暫時的發現是歸到了 .NET Core 3.1 和 5.0 的開發時間線里...后面回來發現這不應該啊
但是...難道就這樣了?
懷著受傷的核桃心, 中午又吃了3只大閘蟹...
詭異的是新建 ASP.NET Core API (.NET Core 3.0) 輸出的 JSON 中文和轉義字符都是正常, 如圖:
說明一定是我們打開的方式不對...回娘家找源碼, 尋尋匿匿最后發現這么一句
// If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters. jsonSerializerOptions = jsonSerializerOptions.Copy(JavaScriptEncoder.UnsafeRelaxedJsonEscaping);less strict?? 那對照的意思是 Newtonsoft.Json 一直使用的就是非嚴格模式咯, 而我們習慣使用的也是這種模式.
那么改下, 還報錯的單元測試都加上配置?JavaScriptEncoder.UnsafeRelaxedJsonEscaping, 果然測試結果順眼多了. 連上面的?UnicodeRanges.All?都不需要配置了.
string bJsonString = System.Text.Json.JsonSerializer.Serialize(value: jsonObject,options: new System.Text.Json.JsonSerializerOptions{Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping});又整明白一個問題, 開森...
總結
以上是生活随笔為你收集整理的.NET Core 3.0 System.Text.Json 和 Newtonsoft.Json 行为不一致问题及解决办法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 知道的越多,越感觉自己渺小
- 下一篇: WinForms项目升级.Net Cor