自定义序列化父级与嵌套对象时嵌套序列化器未触发的问题
解决Newtonsoft.Json自定义转换器中嵌套对象转换器不触发的问题
你遇到的核心问题在于:当你通过JsonConvert.SerializeObject传入转换器数组时,父对象的转换器(PSerializer)内部使用JObject.FromObject序列化嵌套子对象时,并没有复用你传入的转换器集合,而是用了默认的序列化逻辑,导致CSerializer完全没被调用。
修正后的可行代码
public class PItem { public string name = "Parent"; public CItem child = new CItem(); public string type = "P"; } public class CItem { public string name = "Child"; public int prop = 100; public string[] codes = { "122a", "123b" }; } class PSerializer : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { PItem p = value as PItem; JObject jo = JObject.FromObject((PItem)value); var itemProperties = typeof(PItem).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly); var excludeList = new List<string> { "type" }; var itemProps = jo.Properties().Where(x => itemProperties.Any(y => y.Name == x.Name) && !excludeList.Any(y => y == x.Name)); writer.WriteStartObject(); foreach(var itemP in itemProps) { writer.WritePropertyName(itemP.Name); // 关键:使用传入的serializer序列化属性值,会自动匹配对应的转换器 serializer.Serialize(writer, itemP.Value); } writer.WriteEndObject(); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } public override bool CanConvert(Type objectType) { return objectType == typeof(PItem); } } class CSerializer : JsonConverter { public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.Formatting = Formatting.Indented; // 这里的JObject.FromObject不影响,因为CItem没有嵌套需要自定义转换器的对象 JObject jo = JObject.FromObject((CItem)value); jo.Remove("codes"); jo.WriteTo(writer); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { throw new NotImplementedException(); } public override bool CanConvert(Type objectType) { return objectType == typeof(CItem); } } class JSONTest { public string TestConvert() { PItem p = new PItem(); JsonConverter[] serializers = { new PSerializer(), new CSerializer() }; return JsonConvert.SerializeObject(p, serializers); } }
关键修改点说明
- 不再直接输出整个JObject:原来的
jo.WriteTo(writer)会直接序列化整个对象,包括嵌套的child,但这个过程不会使用你传入的转换器数组。 - 手动遍历属性并复用传入的serializer:通过
serializer.Serialize(writer, itemP.Value)序列化每个属性值时,这个serializer实例已经包含了你传入的所有转换器(包括CSerializer),所以当处理child属性(类型为CItem)时,会自动触发CSerializer的逻辑。 - 属性过滤逻辑:通过反射获取PItem的声明属性,再排除指定的冗余字段(比如"type"),确保只序列化需要保留的内容。
这样修改后,父对象和嵌套子对象的自定义转换器都会被正确触发,既移除了冗余数据,又满足了后续还要使用原对象进行其他序列化的需求。
内容的提问来源于stack exchange,提问作者runfastman
相关产品推荐
相关产品推荐

