从Newtonsoft.Json迁移到System.Text.Json?这份避坑指南和完整代码示例请收好

张开发
2026/6/14 4:10:00 15 分钟阅读

分享文章

从Newtonsoft.Json迁移到System.Text.Json?这份避坑指南和完整代码示例请收好
从Newtonsoft.Json迁移到System.Text.Json的实战避坑指南如果你正在维护一个使用Newtonsoft.Json的C#项目可能会考虑迁移到.NET官方推荐的System.Text.Json库。这种迁移不仅能减少第三方依赖还能获得更好的性能表现。但迁移过程并非简单的替换命名空间两个库在API设计、默认行为和扩展机制上存在诸多差异。本文将带你深入剖析迁移过程中的关键挑战并提供可落地的解决方案。1. 迁移前的战略准备在动手修改代码之前需要做好充分的准备工作。我们团队在最近一次大型项目迁移中发现前期规划能减少70%以上的意外问题。首先进行依赖分析使用Visual Studio的解决方案资源管理器或dotnet list package命令统计项目中所有引用Newtonsoft.Json的地方。重点关注直接项目引用间接依赖通过其他NuGet包引入动态加载的插件或模块关键检查点清单项目中Newtonsoft.Json的版本分布使用[JsonProperty]特性的类数量自定义转换器的实现类全局序列化设置的调用位置建立完整的测试覆盖是迁移成功的保障。建议准备三类测试用例// 基础功能测试示例 public class SerializationTests { [Fact] public void BasicObject_ShouldSerializeCorrectly() { var obj new { Name Test, Value 42 }; var json JsonConvert.SerializeObject(obj); var result JsonSerializer.Deserializedynamic(json); Assert.Equal(Test, result.Name.GetString()); } }性能基准测试也不可忽视。可以使用BenchmarkDotNet建立对比测试测试场景Newtonsoft.JsonSystem.Text.Json差异小对象序列化125 ns89 ns29%大对象反序列化1.2 ms0.8 ms33%深度嵌套对象4.5 ms3.1 ms31%2. API差异与行为变更的应对策略两个库最明显的区别在于顶层API设计。Newtonsoft.Json使用静态类JsonConvert而System.Text.Json采用实例模式。这种差异会影响全局配置方式// Newtonsoft.Json全局配置 JsonConvert.DefaultSettings () new JsonSerializerSettings { NullValueHandling NullValueHandling.Ignore, Formatting Formatting.Indented }; // System.Text.Json等效配置 var options new JsonSerializerOptions { DefaultIgnoreCondition JsonIgnoreCondition.WhenWritingNull, WriteIndented true }; // 需要显式传递options到每个序列化调用大小写策略是另一个常见痛点。System.Text.Json默认使用camelCase而Newtonsoft.Json默认保留原始大小写。可以通过以下方式统一行为// Newtonsoft.Json配置 { PropertyNamingPolicy: CamelCase } // System.Text.Json等效配置 new JsonSerializerOptions { PropertyNamingPolicy JsonNamingPolicy.CamelCase }特殊类型处理需要特别注意枚举类型System.Text.Json默认序列化为数字需配置JsonStringEnumConverterDateTimeSystem.Text.Json默认采用ISO 8601格式yyyy-MM-ddTHH:mm:ss.fffZ集合类型空集合处理策略不同3. 自定义转换器的深度改造自定义转换器是迁移过程中最具挑战性的部分。System.Text.Json的转换器接口完全不同需要重写实现逻辑。以下是一个处理特殊日期格式的转换器对比Newtonsoft.Json实现public class CustomDateConverter : JsonConverterDateTime { public override DateTime ReadJson(JsonReader reader, Type type, object value, JsonSerializer serializer) { var str reader.Value.ToString(); return DateTime.ParseExact(str, dd/MM/yyyy, CultureInfo.InvariantCulture); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteValue(((DateTime)value).ToString(dd/MM/yyyy)); } }System.Text.Json等效实现public class CustomDateConverter : JsonConverterDateTime { public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var str reader.GetString(); return DateTime.ParseExact(str, dd/MM/yyyy, CultureInfo.InvariantCulture); } public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { writer.WriteStringValue(value.ToString(dd/MM/yyyy)); } }循环引用处理是另一个关键差异点。Newtonsoft.Json默认支持循环引用检测而System.Text.Json需要显式配置// System.Text.Json循环引用解决方案 options.ReferenceHandler ReferenceHandler.Preserve;这将改变JSON输出结构添加额外的$id和$ref元数据。4. 渐进式迁移实战方案对于大型项目推荐采用渐进式迁移策略。我们团队在实践中总结出三步走方案并行运行阶段1-2周同时引用两个库逐步替换核心模块使用适配器模式统一接口public interface IJsonSerializer { string SerializeT(T obj); T DeserializeT(string json); } // System.Text.Json实现 public class SystemTextJsonSerializer : IJsonSerializer { private readonly JsonSerializerOptions _options; public string SerializeT(T obj) JsonSerializer.Serialize(obj, _options); public T DeserializeT(string json) JsonSerializer.DeserializeT(json, _options); }过渡验证阶段2-4周新旧实现结果对比验证性能监控边缘case测试完全切换阶段1周移除Newtonsoft.Json依赖清理适配器代码更新构建脚本迁移路线图关键节点阶段目标预计耗时风险控制准备影响评估3天建立回滚机制核心模块基础类型处理1周A/B测试业务模块定制逻辑迁移2周分模块验证收尾依赖清理2天全量回归测试5. 性能优化与最佳实践迁移完成后可以通过以下技巧进一步提升System.Text.Json的性能重用JsonSerializerOptions实例对热路径代码使用源生成器合理配置序列化选项源生成器是.NET 6引入的重大改进可以显著提升性能[JsonSerializable(typeof(MyPoco))] public partial class MyJsonContext : JsonSerializerContext {} // 使用生成的序列化代码 var json JsonSerializer.Serialize(obj, MyJsonContext.Default.MyPoco);提示源生成器在AOT编译场景下尤其重要可以完全避免反射开销内存分配优化对比方法分配大小执行时间传统反射1.2 KB450 ns源生成0.4 KB120 ns最后分享几个我们踩过的坑及解决方案异步流处理System.Text.Json的DeserializeAsync方法需要特别注意流的位置管理多态序列化使用[JsonDerivedType]特性替代Newtonsoft的类型转换器动态类型JsonNode类提供了类似JToken的动态访问能力

更多文章