System.Text.Json 的初步接觸 - acaj2018 的部落格 - udn部落格
acaj2018 的部落格
作家:資訊小幫手
文章分類
    Top
    System.Text.Json 的初步接觸
    2026/07/24 11:44:55
    瀏覽:6
    迴響:0
    推薦: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的部分都是序列化、和反序列化,這部分只要改參考即可:

    using System.Text.Json;

    var jsonString = "{\"Name\":\"Small Small Fish\",\"Age\":20, \"Sex\":1, \"SexText\":\"Female\" , \"Desc\":\"non-marine fish\"  }";

    Console.WriteLine(jsonString);

     

    var student = JsonSerializer.Deserialize(jsonString);

    var text = JsonSerializer.Serialize(student);

    預設的序列化和反序列化功能有以下兩點特徵:

    1. Enum屬性預設是轉int
    2. 不會自動縮排

    在使用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:

    1. https://blog.poychang.net/using-json-serializer-with-system-text-json/
    2. https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/ignore-properties
    3. https://blog.darkthread.net/blog/system-text-json/
    回應
    全站分類:知識學習 其他
    自訂分類:技術探討
    下一則: 關聯式陣列 & 匿名函式映射設計

    限會員,要發表迴響,請先登入