Newtonsoft.Json是最稳的JSON处理起点,需注意大小写匹配、无参构造函数、字段可见性、编码处理、异常捕获及日期/HTML转义等细节;System.Text.Json存在兼容性断层,迁移需谨慎。

用 JsonConvert.SerializeObject 和 JsonConvert.DeserializeObject<t></t> 是最稳的起点
Newtonsoft.Json(即 Json.NET)仍是 C# 里读写 JSON 最可靠的选择,尤其在 .NET Framework 和早期 .NET Core 项目中。它不依赖运行时反射优化,类型推导清晰,出错时提示也更贴近实际问题。
常见错误现象:JsonConvert.DeserializeObject<myclass>(json)</myclass> 报 JsonSerializationException,但 JSON 看起来“完全合法”——大概率是字段名大小写不匹配、缺少无参构造函数,或用了 readonly 字段没配 [JsonConstructor]。
- 默认只序列化 public 实例属性/字段;private 或
readonly字段需显式加[JsonProperty] - 反序列化要求目标类型有 public 无参构造函数(除非用
[JsonConstructor]指定) - 如果 JSON 中有额外字段,而类里没有对应属性,默认会静默忽略;加
JsonSerializerSettings.MissingMemberHandling = MissingMemberHandling.Error可提前暴露问题 - 日期格式默认是 ISO 8601,若服务端返回的是 Unix 时间戳或自定义格式,得配
DateTimeZoneHandling或自定义JsonConverter
读文件别直接 File.ReadAllText + DeserializeObject,小心编码和异常
Windows 默认记事本保存的 UTF-8 文件可能带 BOM,File.ReadAllText(path) 在没指定编码时会按系统默认(如 GBK)读取,导致中文乱码或解析失败;更糟的是,JSON 格式错误或文件为空时,DeserializeObject 直接抛异常,没留机会处理空值或日志。
- 读文件务必显式指定编码:
File.ReadAllText(path, Encoding.UTF8) - 先检查文件是否存在、是否为空:
if (!File.Exists(path) || new FileInfo(path).Length == 0) - 用
try/catch包住DeserializeObject,捕获JsonReaderException(可拿到具体行号和位置)和JsonSerializationException - 示例片段:
string json = File.ReadAllText(path, Encoding.UTF8);<br>try {<br> return JsonConvert.DeserializeObject<Config>(json);<br>} catch (JsonReaderException ex) {<br> throw new InvalidOperationException($"JSON 解析失败(第 {ex.LineNumber} 行,第 {ex.LinePosition} 列):{ex.Message}", ex);<br>}
写文件记得用 JsonConvert.SerializeObject 配 Formatting.Indented 和 StringEscapeHandling.EscapeHtml
直接 SerializeObject(obj) 输出的是紧凑 JSON,人眼难读;更隐蔽的问题是,默认不转义 HTML 特殊字符(如 、<code>&),如果 JSON 后续要嵌入 HTML 或被前端 innerHTML 渲染,可能引发 XSS 或解析中断。
- 开发调试阶段加
Formatting.Indented:JsonConvert.SerializeObject(obj, Formatting.Indented) - 若 JSON 会进网页上下文(比如内联 script 标签),加
new JsonSerializerSettings { StringEscapeHandling = StringEscapeHandling.EscapeHtml } - 避免用
File.WriteAllText写完立刻被其他进程读取——考虑先写到临时文件,再File.Move原子替换,防止读到半截内容 - 注意
DateTime序列化:默认输出带时区信息(如"2024-05-20T14:30:00+08:00"),若后端只要日期或 UTC,设DateTimeZoneHandling = DateTimeZoneHandling.Utc
.NET 6+ 用 System.Text.Json?先看清兼容性断层
虽然微软主推 System.Text.Json,但它和 Newtonsoft.Json 在行为上有多处不兼容:比如默认不支持循环引用、不支持 DataSet/DataTable、对字典 key 的类型限制更死(只接受 string)、JsonElement 不可变导致修改成本高。很多老项目迁过去后,JsonConvert.DeserializeObject<dictionary object>></dictionary> 这种灵活写法直接崩。
- 如果你的项目已重度依赖
JObject、JArray动态操作,或用了大量自定义JsonConverter,别硬切System.Text.Json -
System.Text.Json的JsonSerializerOptions.PropertyNamingPolicy默认是驼峰,Newtonsoft 默认是原样;迁移时字段名大小写错位是高频坑 - 若必须共存(比如部分模块用新库),注意两个库对同一对象序列化的结果可能不同——尤其是
null值处理、浮点数精度、DBNull映射
真正麻烦的不是语法怎么写,而是 JSON 结构松散、上下游契约模糊时,序列化器替你做的“自动适配”反而掩盖了数据不一致。宁可多写几行验证逻辑,也别信默认行为。


















