system.text.json序列化抛 notsupportedexception 时,需针对 datetimeoffset(加jsondatetimeoffsetconverter)、dictionary(改用强类型或jsonnode)、循环引用(.net 6+启用referencehandler.preserve)、大小写不匹配(设camelcase或jsonpropertyname)、可空类型(启用nullable并配defaultignorecondition)及jobject迁移(优先jsonnode或强类型)分别处理。

System.Text.Json序列化时抛出 NotSupportedException 怎么办
常见于尝试序列化 DateTimeOffset、Dictionary<string object></string> 或含循环引用的对象。System.Text.Json 默认不支持这些类型,也不做运行时类型推断。
实操建议:
- 用
JsonSerializerOptions.WriteIndented = true便于调试输出 - 对
DateTimeOffset,显式设置options.Converters.Add(new JsonStringEnumConverter())不起作用,得加new JsonDateTimeOffsetConverter()(需自定义)或改用DateTime - 避免直接序列化
object类型字典;优先用强类型类,或改用JsonDocument.Parse()+ 手动构建JsonObject - 循环引用会直接炸,没有
ReferenceHandler.Preserve之前版本(.NET 6+)请确认 SDK 版本 ≥6.0
反序列化时字段名大小写不匹配(如 JSON 是 user_name,C# 属性是 UserName)
Newtonsoft 默认忽略大小写,System.Text.Json 默认严格匹配,字段名对不上就为 null 或跳过赋值。
实操建议:
- 全局启用驼峰命名:设置
options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase - 单个属性控制:在字段上加
[JsonPropertyName("user_name")](注意不是[JsonProperty]) - 若 JSON 字段含横线(如
api-key),必须用[JsonPropertyName("api-key")],命名策略无效 - 别依赖
options.IgnoreNullValues = true来掩盖字段没映射的问题——它只影响序列化输出
需要处理 null 值或可空引用类型(string?、MyClass?)
System.Text.Json 对可空引用类型(C# 8+ 的 nullable reference types)默认不特殊处理,null 输入可能被静默丢弃,或反序列化失败。
实操建议:
- 确保项目启用
<nullable>enable</nullable>,否则编译器不校验,但运行时仍可能出错 - 反序列化含
null的 JSON 到非可空字段(如string Name)会抛JsonException;改为string? Name并配options.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull - 若需把 JSON 中缺失字段也视为
null(而非默认值),加上options.DefaultIgnoreCondition = JsonIgnoreCondition.Never并配合[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
从 Newtonsoft 迁移时,JObject / JArray 对应什么
没有直接等价物。JObject 是动态容器,System.Text.Json 的 JsonDocument 是只读的,JsonObject(.NET 7+)才支持可变操作,但 API 完全不同。
实操建议:
- 轻量读取:用
JsonDocument.Parse(json)→RootElement.GetProperty("items")→ 遍历EnumerateArray() - 需要修改再写回:优先转成强类型对象,或用
JsonNode.Parse(json)(.NET 6+,支持AsObject()/AsArray()) -
JsonNode不是零成本抽象,频繁读写比JsonDocument慢;高频场景仍建议静态模型 +JsonSerializer - 别试图用
JsonSerializer.Deserialize<object>()</object>模拟JObject——它只会变成Dictionary<string object></string>,嵌套结构丢失类型信息
最易被忽略的是:System.Text.Json 的异常信息非常简略,比如 Cannot get the value of a token type 'StartObject' as a string. 这类报错几乎不指明位置,调试时务必先用 JsonDocument.Parse() 确认 JSON 结构合法,再切到强类型路径。










