【茶包射手雜記】JObject 無法被 System.Text.Json 序列化
0 |
.NET Core 開始內建 System.Text.Json,強調效能快、省記憶體,計劃逐步取代 Json.NET。從 .NET Core 3 一路發展,System.Text.Json 加入 JsonObject、JsonArray 支援 DOM 巡覽及 JSON 文件編修,功能及順手度慢慢追上 Json.NET。但就實務面,Json.NET 有大量現成範例、程式庫滿足五花八門需求,為求統一硬要全面改寫成 System.Text.Json 並非明智之舉。於是,專案混用 System.Text.Json 與 Json.NET 的案例還蠻常見的。
最近遇到一例,ASP.NET Core Minimal API 整合現有程式庫,方法回傳類型為 JObject,我沒想太多,就用 Results.Json() 打算將其轉為 JSON 傳回前端:
using System.Text.Json;
using Newtonsoft.Json.Linq;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => Results.Json(someLegacyApi()));
app.Run();
JObject someLegacyApi() => new JObject
{
["cpu"] = "i7",
["os"] = new JObject
{
["ver"] = "Windows 11",
["lang"] = "en-US",
},
["drives"] = new JArray
{
"SSD 1TB", "HDD 2TB"
}
};
預期該傳回 {"cpu":"i7","os":{"ver":"Windows 11","lang":"en-US"},"drives":["SSD 1TB","HDD 2TB"]}
,結果得到 {"cpu":[],"os":[[[]],[[]]],"drives":[[],[]]}
這種鬼東西:
我很快明白,JObject 是 Json.NET 特製的類別,無法像一般類別用 Reflection GetProperties() 列舉屬性,Json.NET 是自己加上訂製邏輯才能順利序列化。而要解這個問題不難,先將 JObject 轉成 JSON 字串,再反序列化還原成 System.Text.Json 世界的類別,之後即可暢行無阻。
試了兩種寫法:JsonSerializer.Deserialize<JsonElement>()
及 JsonDocument.Parse()
,都能順利解決問題:
app.MapGet("/jsonelem", () => Results.Json(
JsonSerializer.Deserialize<JsonElement>(someLegacyApi().ToString())));
app.MapGet("/jsondoc", () => Results.Json(
JsonDocument.Parse(someLegacyApi().ToString())));
Tips of how to serialize JObject with System.Text.Json.
Comments
Be the first to post a comment