直接用
System.Text.Json的
JsonSerializer.Deserialize<t>()</t>是最推荐的方式,.NET 5+ 默认启用、性能高、无额外依赖;若需兼容旧项目或特殊功能(如 camelCase 自动转换、循环引用),才考虑
Newtonsoft.Json。
用 System.Text.Json 反序列化基础对象
这是 .NET Core 3.0 起内置的高性能 JSON 库,无需安装 NuGet 包(除非 targeting .NET Framework)。
常见错误:传入 null 字符串、类型不匹配、JSON 字段名与 C# 属性名不一致导致字段为默认值。
确保目标类属性为public,或用
[JsonPropertyName("xxx")] 显式映射字段名
若 JSON 是驼峰(userName),C# 属性是 PascalCase(
UserName),需配置
JsonSerializerOptions.PropertyNameCaseInsensitive = true反序列化数组或集合时,确保目标类型是具体泛型类型(如
List<user></user>),而非
IEnumerable<user></user>
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var user = JsonSerializer.Deserialize<User>(jsonString, options);处理 Newtonsoft.Json 的常见兼容场景
老项目或需要
JsonIgnore、
JsonConverter等高级特性时仍会用到它。注意它和
System.Text.Json的行为差异较大。
典型问题:日期格式解析失败、空字符串转 null 报错、自定义 converter 不生效。
JsonConvert.DeserializeObject<t>(json)</t>是入口函数,不是静态类方法 使用
NullValueHandling.Ignore或
DefaultValueHandling.Ignore控制空值行为 若 JSON 中有
"date": "2023-01-01",而 C# 属性是
DateTime?,默认能解析;但若含时区(
"2023-01-01T00:00:00Z"),建议显式设
DateFormatHandling = DateFormatHandling.IsoDateFormat
var settings = new JsonSerializerSettings
{
NullValueHandling = NullValueHandling.Ignore,
DateParseHandling = DateParseHandling.DateTime
};
var data = JsonConvert.DeserializeObject<Order>(jsonString, settings);反序列化未知结构或动态内容
当 JSON 结构不确定(比如 API 返回字段随版本变化),别硬套强类型,优先用
JsonDocument或
JsonElement解析。
容易踩的坑:用完没调
doc.Dispose()导致内存泄漏;或误把
JsonElement.Clone()当深拷贝(其实只是复制引用)。
JsonDocument.Parse(jsonString)返回只读树结构,适合只读查询 需要修改或构建新 JSON 时,用
JsonObject(.NET 6+)或
JObject(Newtonsoft) 提取字段值前务必检查
element.TryGetProperty("xxx", out var value),避免 KeyNotFoundException
using var doc = JsonDocument.Parse(jsonString);
var root = doc.RootElement;
if (root.TryGetProperty("status", out var status))
{
Console.WriteLine(status.GetString());
}反序列化失败时怎么快速定位
抛出异常是常态,关键是怎么看懂错误信息。两种库的异常提示风格完全不同。
System.Text.Json错误通常带位置(如
LineNumber: 3, BytePositionInLine: 12),但不告诉你“期望什么类型”;
Newtonsoft.Json提示更口语化(如
Cannot convert string to int),但位置信息弱。 先确认 JSON 是否合法(用在线工具或
JsonDocument.Parse尝试解析) 检查目标类型的构造函数:默认必须有 public parameterless 构造函数(
System.Text.Json不支持私有构造) 遇到
NotSupportedException: Deserialization of reference types without parameterless constructor is not supported,说明类写了带参构造且没留无参构造
复杂嵌套对象或自定义 converter 场景下,别依赖一次性全量反序列化——分步解析字段更可控,也更容易加日志。
