改寫 .NET Core 之後,我都盡量改用 System.Text.Json處理 JSON,做個不守舊,擁抱新時代的老人。System.Text.Json 主打高效能,雖然功能跟擴充性比不上 Json.NET 完整,但身為 .NET 內建元件,不用擔心支援性及整合度,預期會持續強化(例如:.NET 6 開始支援 DOM 操作)。只是,從 Json.NET 切換到 System.Text.Json,還是有些地方需要調整適應,像是預設中文會轉為 UCN (例如:"\u9ED1\u6697\u57F7\u884C\u7DD2") 格式、屬性名稱強制轉小寫起始的行為,便與 Json.NET 的預設做法不同,但都有選項可調,移轉程式時需留意。

今天再碰上一則 Json.NET 轉換 System.Text.Json 相容問題,某段 Web API 程式搬到 ASP.NET Core 後,傳回結果一片空白,JSON 只剩個空殼 。仔細一查,發現是因為內容值被設成 Field 而非 Property,Json.NET 序列化物件時,預設會涵蓋 Field,但 System.Text.Json 不會,所幸加個 IncludeFields 選項即可調整。

我寫了一個範例展示 Json.NET 與 System.Text.Json 處理 Field 的差異,以及如何透過 IncludeFields 參數改變行為。

// 請參照 Json.NET => dotnet add package Newtonsoft.Json
var demo = new JsonDemo {
    PropTest = "ABC",
    FldTest = "123"
};

print("Json.NET", ConsoleColor.Magenta);
print(Newtonsoft.Json.JsonConvert.SerializeObject(demo));
print("System.Text.Json", ConsoleColor.Cyan);
print(System.Text.Json.JsonSerializer.Serialize(demo));
print("System.Text.Json with IncludeFields option", ConsoleColor.Yellow);
print(System.Text.Json.JsonSerializer.Serialize(demo,
    new System.Text.Json.JsonSerializerOptions {
        IncludeFields = true
    }));

void print(string m, ConsoleColor? c = null) {
    if (c != null) Console.ForegroundColor = c.Value;
    else Console.ForegroundColor = ConsoleColor.White;
    Console.WriteLine(m);
}

public class JsonDemo {
    public string PropTest { get; set;} = string.Empty;
    public string FldTest = string.Empty;
}

範例還順便展示 .NET 6 Program.cs 宣告自訂函式及類別的寫法,免洗程式或簡單應用,這樣就夠了。

題外話,上回保哥有則貼文聊到很多老兵對 .NET 6 的 Top-Level Statement 超級反感,顯然我是罕見的少數。開始幾天得花點時間習慣,上手後便覺得用 .NET 6 寫小範例超輕鬆,不用管 using、namespace、class、void Main(),直接切入主題,簡單幾行打死,讀者朋友 Copy Paste 貼進 Program.cs 即可執行重現,奉行 KISS 主義熱愛極簡風的我,一見就愛上。

現在,只要想到什麼點子,開 Cmder,dotnet new console -o test-proj 就開始試寫,加上輕巧的 VSCode,寫 C# 這件事變得好輕鬆。

給 .NET 6 按個讚!

System.Text.Json doesn't include fields bye default, which is different from Json.NET, and we can set JsonSerializerOptions to change it.


Comments

Be the first to post a comment

Post a comment