C#中序列化格式变更时类、JSON、反序列化兼容的最优处理方式
最优方案:使用序列化框架内置的自定义转换器实现兼容
你提到的两种方案都有明显缺陷:
- 动态读取JSON后判断格式:需要额外编写通用JSON节点遍历逻辑,代码冗余,结构复杂时容易遗漏边界场景
- try/catch捕获反序列化失败:异常捕获存在固定性能开销,且无法区分反序列化失败是旧格式导致还是数据本身损坏,不利于后续问题排查
通过自定义JsonConverter的方案可以完美解决需求,同时兼顾性能、可维护性和鲁棒性,读取时自动识别新旧格式转换为新结构,写入时统一输出新格式,兼容逻辑完全和业务代码解耦。具体实现如下:
首先统一业务实体定义:
public class OrgHierarchyItem { public string Key { get; set; } public string Value { get; set; } }
如果你用.NET自带的System.Text.Json
自定义转换器实现:
using System.Text.Json; using System.Text.Json.Serialization; public class OrgHierarchyConverter : JsonConverter<List<OrgHierarchyItem>> { public override List<OrgHierarchyItem> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var result = new List<OrgHierarchyItem>(); if (reader.TokenType != JsonTokenType.StartArray) throw new JsonException("OrgHierarchy must be an array"); while (reader.Read()) { if (reader.TokenType == JsonTokenType.EndArray) return result; // 元素为字符串则是旧格式,默认Value和Key一致,可根据业务调整默认值 if (reader.TokenType == JsonTokenType.String) { var key = reader.GetString(); result.Add(new OrgHierarchyItem { Key = key, Value = key }); } // 元素为对象则是新格式,直接反序列化 else if (reader.TokenType == JsonTokenType.StartObject) { var item = JsonSerializer.Deserialize<OrgHierarchyItem>(ref reader, options); result.Add(item); } } throw new JsonException("Unexpected end of JSON when parsing OrgHierarchy"); } public override void Write(Utf8JsonWriter writer, List<OrgHierarchyItem> value, JsonSerializerOptions options) { // 写入统一用新格式 JsonSerializer.Serialize(writer, value, options); } }
给属性加特性绑定转换器即可:
[JsonConverter(typeof(OrgHierarchyConverter))] public List<OrgHierarchyItem> OrgHierarchy { get; set; } = new List<OrgHierarchyItem>();
如果你用Newtonsoft.Json(Json.NET)
自定义转换器实现:
using Newtonsoft.Json; using Newtonsoft.Json.Linq; public class OrgHierarchyConverter : JsonConverter<List<OrgHierarchyItem>> { public override List<OrgHierarchyItem> ReadJson(JsonReader reader, Type objectType, List<OrgHierarchyItem> existingValue, bool hasExistingValue, JsonSerializer serializer) { var result = new List<OrgHierarchyItem>(); var array = JArray.Load(reader); foreach (var item in array) { if (item.Type == JTokenType.String) { var key = item.Value<string>(); result.Add(new OrgHierarchyItem { Key = key, Value = key }); } else if (item.Type == JTokenType.Object) { result.Add(item.ToObject<OrgHierarchyItem>(serializer)); } } return result; } public override void WriteJson(JsonWriter writer, List<OrgHierarchyItem> value, JsonSerializer serializer) { serializer.Serialize(writer, value); } }
给属性加特性绑定转换器即可:
[JsonConverter(typeof(OrgHierarchyConverter))] public List<OrgHierarchyItem> OrgHierarchy { get; set; } = new List<OrgHierarchyItem>();
内容的提问来源于stack exchange,提问作者Chris Ward
相关产品推荐
相关产品推荐

