17370845950

C# JSON反序列化方法 C#如何实现JSON反序列化
推荐优先使用 System.Text.Json.Deserialize(),.NET 5+ 默认启用、性能高;仅在需 camelCase 转换、循环引用等特殊功能时选用 Newtonsoft.Json,并注意二者行为差异。

直接用 System.Text.JsonJsonSerializer.Deserialize() 是最推荐的方式,.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),而非 IEnumerable
var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};
var user = JsonSerializer.Deserialize(jsonString, options);

处理 Newtonsoft.Json 的常见兼容场景

老项目或需要 JsonIgnoreJsonConverter 等高级特性时仍会用到它。注意它和 System.Text.Json 的行为差异较大。

典型问题:日期格式解析失败、空字符串转 null 报错、自定义 converter 不生效。

  • JsonConvert.DeserializeObject(json) 是入口函数,不是静态类方法
  • 使用 NullValueHandling.IgnoreDefaultValueHandling.Ignore 控制空值行为
  • 若 JSON 中有 "date": "2025-01-01",而 C# 属性是 DateTime?,默认能解析;但若含时区("2025-01-01T00:00:00Z"),建议显式设 DateFormatHandling = DateFormatHandling.IsoDateFormat
var settings = new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore,
    DateParseHandling = DateParseHandling.DateTime
};
var data = JsonConvert.DeserializeObject(jsonString, settings);

反序列化未知结构或动态内容

当 JSON 结构不确定(比如 API 返回字段随版本变化),别硬套强类型,优先用 JsonDocumentJsonElement 解析。

容易踩的坑:用完没调 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 场

景下,别依赖一次性全量反序列化——分步解析字段更可控,也更容易加日志。