使用Newtonsoft JSON如何不修改类属性实现列表/字典条件序列化
实现方案
步骤1:定义序列化格式控制枚举
你可以借助JsonSerializer内置的StreamingContext传递自定义配置,先定义枚举标记需要的输出格式:
public enum ItemsSerializationFormat { AsArray, AsDictionary }
步骤2:实现自定义JsonConverter
该Converter会自动读取上下文中的配置,切换输出格式,不需要修改原有类的任何特性:
public class ChildItemsConverter : JsonConverter<List<ChildClass>> { public override void WriteJson(JsonWriter writer, List<ChildClass> value, JsonSerializer serializer) { // 从序列化上下文读取格式配置 if (serializer.Context.Context is ItemsSerializationFormat format && format == ItemsSerializationFormat.AsDictionary) { // 转换为字典输出 var dict = value.ToDictionary(item => item.IDProperty); serializer.Serialize(writer, dict); return; } // 默认输出数组格式 serializer.Serialize(writer, value); } public override List<ChildClass> ReadJson(JsonReader reader, Type objectType, List<ChildClass> existingValue, bool hasExistingValue, JsonSerializer serializer) { // 按需实现反序列化逻辑,不需要可直接抛出异常 throw new NotImplementedException(); } }
步骤3:调用时按需切换格式
调用JObject.FromObject时传入携带对应配置的JsonSerializer即可:
输出数组格式
var serializer = new JsonSerializer(); serializer.Converters.Add(new ChildItemsConverter()); // 传入数组格式配置 serializer.Context = new StreamingContext(StreamingContextStates.All, ItemsSerializationFormat.AsArray); JObject result = JObject.FromObject(myClassInstance, serializer);
输出字典格式
var serializer = new JsonSerializer(); serializer.Converters.Add(new ChildItemsConverter()); // 传入字典格式配置 serializer.Context = new StreamingContext(StreamingContextStates.All, ItemsSerializationFormat.AsDictionary); JObject result = JObject.FromObject(myClassInstance, serializer);
实现原理
Newtonsoft.Json的JsonSerializer.Context属性本身就是官方提供的自定义参数传递入口,你可以把任意自定义对象放到StreamingContext的Context字段中,在Converter内部直接读取,全程不需要修改原有业务类的代码。
内容的提问来源于stack exchange,提问作者ChristopherBass
相关产品推荐
相关产品推荐

