带JObject类型的公共契约从Newtonsoft迁移至System.Text.Json并保持向后兼容
跨Json序列化库兼容JObject的解决方案
原契约代码
using Newtonsoft.Json; using Newtonsoft.Json.Linq; public class Foo { [JsonProperty("type")] public int Type { get; set; } [JsonProperty("value")] public JObject Value { get; set; } }
场景说明
该契约被两个独立微服务使用:一个计划切换为System.Text.Json替代Newtonsoft.Json,另一个仍会在一段时间内继续使用Newtonsoft.Json。需要解决Value属性(类型为Newtonsoft的JObject)的跨序列化库兼容问题。
可行处理方案
方案一:改用通用兼容类型+双序列化特性(推荐长期迁移)
将Value的类型替换为System.Text.Json的JsonElement,同时添加两种序列化库的特性标记,再通过扩展方法实现JsonElement与JObject的互转,兼顾两个服务的使用需求。
修改后的代码:
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Text.Json.Serialization; public class Foo { [JsonProperty("type")] [JsonPropertyName("type")] public int Type { get; set; } [JsonProperty("value")] [JsonPropertyName("value")] public JsonElement Value { get; set; } // 给使用Newtonsoft的服务提供JObject转换方法 public JObject GetValueAsJObject() { return JObject.Parse(System.Text.Json.JsonSerializer.Serialize(Value)); } // 给需要从JObject赋值的场景提供方法 public void SetValueFromJObject(JObject jObject) { var jsonStr = jObject.ToString(); Value = System.Text.Json.JsonSerializer.Deserialize<JsonElement>(jsonStr); } }
优点:逐步摆脱对Newtonsoft类型的依赖,符合长期迁移到System.Text.Json的规划;两个服务无需额外配置即可正常序列化/反序列化。
方案二:自定义System.Text.Json转换器(适合临时兼容)
如果不想修改Value的原有类型,可针对System.Text.Json编写自定义转换器,实现JObject与JSON数据的直接转换,Newtonsoft服务则保持原有逻辑不变。
- 编写自定义转换器:
using Newtonsoft.Json.Linq; using System.Text.Json; using System.Text.Json.Serialization; public class JObjectSystemTextJsonConverter : JsonConverter<JObject> { public override JObject Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var jsonStr = reader.GetString(); return !string.IsNullOrEmpty(jsonStr) ? JObject.Parse(jsonStr) : new JObject(); } public override void Write(Utf8JsonWriter writer, JObject value, JsonSerializerOptions options) { writer.WriteRawValue(value.ToString(Newtonsoft.Json.Formatting.None)); } }
- 修改契约类,添加转换器标记:
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Text.Json.Serialization; public class Foo { [JsonProperty("type")] [JsonPropertyName("type")] public int Type { get; set; } [JsonProperty("value")] [JsonPropertyName("value")] [JsonConverter(typeof(JObjectSystemTextJsonConverter))] public JObject Value { get; set; } }
优点:无需改动原有类型定义,适配现有使用JObject的业务逻辑;仅需在使用System.Text.Json的服务中引入转换器即可。
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

