上一篇文章提到從 Newtonsoft.Json 遷移到 System.Text.Json 的實際經驗,這篇專注在兩者的功能與行為差異,讓你在選型時有具體依據。
歷史背景
Newtonsoft.Json(又稱 Json.NET)由 James Newton-King 於 2006 年首次發布,長期是 .NET 生態系的預設 JSON 工具。ASP.NET Core 2.x 的 MVC 框架預設使用它進行模型序列化,直到 ASP.NET Core 3.0 才改為 System.Text.Json。
System.Text.Json 隨 .NET Core 3.0(2019 年)一起推出,由微軟直接整合進執行時期,設計目標是效能與低配置開銷——代價是功能集比 Newtonsoft.Json 精簡。
效能
根據 BenchmarkDotNet 的公開測試,System.Text.Json 的序列化吞吐量約比 Newtonsoft.Json 快 20–35%。記憶體配置差距因資料形狀差異很大:小物件可能只差一點,大批次 JSON 串流場景下 System.Text.Json 因避免中間字串配置,記憶體佔用明顯更低。不建議直接套用任何網路上的數字——用 BenchmarkDotNet 在自己的資料結構上實測最準。
效能差距較明顯的情境:
- 高吞吐量 Web API(大量小物件反覆序列化)
- 串流處理大型 JSON 檔案(
Utf8JsonReader/Utf8JsonWriter)
效能差距不明顯的情境:
- 一次性批次工作
- JSON 結構複雜、需要大量自訂轉換邏輯(轉換成本蓋過引擎差距)
功能差異
循環參考處理
這是兩者行為差距最大的地方之一。
1 | // Newtonsoft.Json:可設定忽略循環參考 |
如果你的物件圖有循環參考(例如 EF Core 的導覽屬性雙向關聯),遷移時這個差異最容易炸。
多型 / 派生型別序列化
Newtonsoft.Json 透過 TypeNameHandling 或自訂 JsonConverter 長期支援多型序列化。System.Text.Json 要到 .NET 7 才內建 [JsonDerivedType] 屬性:
1 | // System.Text.Json(.NET 7+) |
.NET 6 以下若需要多型序列化,只能自己實作 JsonConverter<T>,或繼續用 Newtonsoft.Json。
Source Generator 支援
System.Text.Json 從 .NET 6 起支援 Source Generator 模式,在編譯期產生序列化程式碼,完全避開執行期反射:
1 | [] |
這對 AOT 編譯(Native AOT)和啟動效能要求高的場景幾乎是必選。Newtonsoft.Json 目前不支援 Source Generator,AOT 相容性也較差。
自訂命名規則
1 | // System.Text.Json |
動態物件處理
1 | // System.Text.Json(.NET 6+ JsonNode API) |
自訂型別轉換
兩者都有泛型版本的 Converter,型別安全性相當:
1 | // System.Text.Json |
非同步支援
System.Text.Json 設計上就以串流為核心,JsonSerializer.DeserializeAsync 直接接受 Stream,不需要先讀成字串。Newtonsoft.Json 也有 JsonTextReader 搭配 StreamReader 的非同步用法,但 API 層次不同,使用起來較繁瑣。高吞吐量 API 若在意配置開銷,這個差距值得測試。
遷移注意事項
從 Newtonsoft.Json 換到 System.Text.Json,常見踩坑點:
- 屬性名稱大小寫:Newtonsoft 預設 case-insensitive 反序列化,STJ 預設 case-sensitive,要加
PropertyNameCaseInsensitive = true [JsonProperty]屬性:Newtonsoft 的標記在 STJ 無效,要換成[JsonPropertyName][JsonIgnore]條件:STJ 的[JsonIgnore(Condition = ...)]語義和 Newtonsoft 不完全相同- 循環參考:如前述,Newtonsoft 預設不報錯,STJ 預設拋例外
object型別反序列化:Newtonsoft 遇到object屬性會推斷成JObject/JArray,STJ 推斷成JsonElementDateTime格式:兩者對非標準日期格式的容忍度不同,手動指定格式是最保險的做法
選型建議
新專案用 System.Text.Json,理由很直接:效能更好、是 .NET 執行時期的一部分、Native AOT 相容、長期方向明確。
以下情境考慮繼續用 Newtonsoft.Json 或延後遷移:
- 現有程式碼大量依賴
JObject/JToken動態操作 - 需要
ReferenceLoopHandling.Ignore且無法修改物件圖 - 用到 Newtonsoft 特有的
JsonConverter生態(如Newtonsoft.Json.Schema) - 目標框架低於 .NET 6,或需要相容 .NET Framework
兩者並存也是選項:ASP.NET Core 可以只在特定端點或服務層換成 STJ,其餘保留 Newtonsoft.Json,不需要一次全換。




