字體:小 中 大 |
|
|
|
| 2026/07/24 11:44:55瀏覽3|回應0|推薦0 | |
在微軟官方網站上檢視.NET 8新功能時,看到一句話:「.NET 8 中的 System.Text.Json 序列化和還原序列化功能進行許多改進。」當下腦袋充滿了各種問號,因為當時的我對Json的認知都還停留在Newtonsoft.Json這套件上,後來上網查了一下才知道:微軟早在.NET Core 3.0開始就內建 System.Text.Json 做為預設Json處理核心,也是為了擺脫對Json.Net的依賴。 記得早期有一段時期,.NET Framework 4點多的時候,曾經因為發佈出來的程式版本與config中指定的Newtonsoft.Json版本不合而去更新Newtonsoft.Json組件、或追加調整config指定版本;現在回想起來,如果這部分可以直接採用內建套件、就不會再擔心發生版本差異的問題了。 發展至今,System.Text.Json是否可以完整取代Newtonsoft.Json我不知道,但我針對性的以公司內常用的Json功能進行檢查:幾乎可以說是換掉namespace命名空間即可;而少部分有差異的地方才需要調整程式碼。 在此先補充說明:此篇文章僅針對公司內常用功能進行檢查,不做效能判斷,一來是公司內較少需要大量且頻繁地進行Json資料轉換,其次兩種套件的效能比較早在.NET Core 3.0的版本時就有,僅附網址提供參考:https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/?WT.mc_id=DOP-MVP-37580 開發程式中約有八到九成使用Json的部分都是序列化、和反序列化,這部分只要改參考即可:
預設的序列化和反序列化功能有以下兩點特徵:
在使用Serialize的過程中,最常注意的就是縮排,預設沒有自動縮排這一點對我來說是比較好,因為比較節省空間、尤其是寫Log的時候,但對有的人來說並不友善,因為有了縮排才好檢視。 在這方面,System.Text.Json與Newtonsoft.Json不同,使用的物件屬性名稱有一點差異、需要微調程式碼。 Newtonsoft.Json是使用JsonSerializerSettings、其屬性是Formatting為enum: var setting = new JsonSerializerSettings { Formatting = Newtonsoft.Json.Formatting.None }; JsonConvert.SerializeObject(value, setting); System.Text.Json則是使用JsonSerializerOptions、其屬性是WriteIndented為bool: var options = new JsonSerializerOptions { WriteIndented = true }; var text2 = JsonSerializer.Serialize(student, options); 除此之外,常見且比較有可能用到的諸如:enum屬性不是轉為int而是轉為string的話、或是屬性名稱有所差異等,都可以依靠追加attribute來支援的功能: public enum StudentSex { Male = 0, Female = 1 } public class Student { public string Name { get; set; } public int Age { get; set; } public StudentSex Sex { get; set; } [JsonConverter(typeof(JsonStringEnumConverter))] public StudentSex SexText { get; set; } public int No { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string Tag { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public string Address1 { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.Always)] public string Address2 { get; set; } [JsonPropertyName("Desc")] public string Description { get; set; } } 如此一來,同樣是enum,但Sex為數值、SexText則為文字;且程式中Description的屬性在Json字串內則是Desc。 var jsonString = "{\"Name\":\"Small Small Fish\",\"Age\":20, \"Sex\":1, \"SexText\":\"Female\", \"Address2\": \"test\", \"Tag\": null, \"No\": 0, \"Desc\":\"non-marine fish\" }"; var student = JsonSerializer.Deserialize(jsonString); var text1 = JsonSerializer.Serialize(student, JsonSerializerOptions.Default); Console.WriteLine("serialize by default:"); Console.WriteLine(text1); Console.WriteLine(); var options = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip, WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault, }; var text2 = JsonSerializer.Serialize(student, options); Console.WriteLine("serialize by options:"); Console.WriteLine(text2); 程式執行結果:
其中,Ignore忽略轉換功能比較特殊,可透過attribute指定特定屬性支援、也可以直接透過序列化設定進行指定,而且除了null以外也可以指定default值就進行忽略(例如int的default值為0),或是Always一直忽略轉換該屬性、Never一直不能忽略該屬性。 雖然System.Text.Json我是在Net8推出之後才開始接觸,但文中上述程式碼卻並非都是.NET 8才可以使用,至少.NET 6運作無誤。 Reference: |
|
| ( 知識學習|其他 ) |












