如何在Flurl/Json.net中兼容JSON载荷的向后破坏性变更?
你的思路核心是可行的,仅需要调整转换器的泛型适配目标类型即可:不要继承JsonConverter<string>,改为直接继承JsonConverter<List<string>>,这样读写逻辑都能匹配你List<string>类型的属性。
完整实现代码
自定义Json转换器
using Newtonsoft.Json; using Newtonsoft.Json.Linq; internal class ConvertCsvStringToArray : JsonConverter<List<string>> { // 序列化输出规则:对接旧版API入参设为true输出逗号分隔字符串,对接新版API设为false输出数组,可按需调整 public bool SerializeAsCsvString { get; set; } = false; public override List<string>? ReadJson(JsonReader reader, Type objectType, List<string>? existingValue, bool hasExistingValue, JsonSerializer serializer) { // 处理null值 if (reader.TokenType == JsonToken.Null) return new List<string>(); // 识别到旧版字符串格式,走拆分逻辑 if (reader.TokenType == JsonToken.String) { string? csvStr = reader.Value?.ToString(); if (string.IsNullOrWhiteSpace(csvStr)) return new List<string>(); // 按逗号拆分,自动移除元素前后空格、过滤空项 return csvStr.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList(); } // 识别到新版数组格式,走默认数组反序列化逻辑 if (reader.TokenType == JsonToken.StartArray) { return serializer.Deserialize<List<string>>(reader) ?? new List<string>(); } // 异常格式默认返回空数组,也可根据业务需求抛出异常 return new List<string>(); } public override void WriteJson(JsonWriter writer, List<string>? value, JsonSerializer serializer) { if (value == null) { writer.WriteNull(); return; } if (SerializeAsCsvString) { // 序列化为逗号分隔字符串,适配旧版API入参要求 writer.WriteValue(string.Join(", ", value)); } else { // 序列化为标准JSON数组,适配新版API入参要求 serializer.Serialize(writer, value); } } }
实体类配置
public class Payload { // 如果需要序列化输出逗号分隔字符串,可修改为 [JsonConverter(typeof(ConvertCsvStringToArray), SerializeAsCsvString = true)] [JsonConverter(typeof(ConvertCsvStringToArray))] public List<string> Values { get; set; } = new(); }
使用效果
配置完成后你原有Flurl调用代码不需要做任何修改,反序列化时会自动识别API返回的格式,统一转换为List<string>类型;序列化时也可以根据对接的API入参要求灵活选择输出格式,所有转换逻辑对上层业务代码完全透明,不需要维护多版本实体类。
内容的提问来源于stack exchange,提问作者void.pointer
相关产品推荐
相关产品推荐

