如何在System.Text.Json中实现反序列化回调并避免递归循环?
解决System.Text.Json自定义转换器反序列化无限递归问题
问题根因
你的Animal类标记了[JsonConverter(typeof(AnimalCallbacksConverter))]特性,导致每次调用JsonSerializer.Deserialize<Animal>(ref reader)时,序列化框架都会自动触发这个自定义转换器,进而在Read方法内反复调用自身,形成无限递归。
可行解决方案
核心思路是创建一个移除了当前自定义转换器的新JsonSerializerOptions,用这个新选项调用Deserialize,既保留框架自动反序列化的便捷性,又能插入自定义回调逻辑。
修改后的自定义转换器代码
public class AnimalCallbacksConverter : JsonConverter<Animal> { public override Animal Read( ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { Console.WriteLine("OnDeserializing"); // 复制原配置,移除当前转换器避免递归 var newOptions = new JsonSerializerOptions(options); newOptions.Converters.Remove(this); // 用新选项执行默认反序列化 Animal animal = JsonSerializer.Deserialize<Animal>(ref reader, newOptions); Console.WriteLine("OnDeserialized"); // 在这里添加你的后续逻辑,比如初始化操作、属性修正等 // 示例:animal.Id = $"processed_{animal.Id}"; return animal; } public override void Write( Utf8JsonWriter writer, Animal value, JsonSerializerOptions options) { Console.WriteLine("OnSerializing"); // 序列化端同理处理,避免递归 var newOptions = new JsonSerializerOptions(options); newOptions.Converters.Remove(this); JsonSerializer.Serialize(writer, value, newOptions); Console.WriteLine("OnSerialized"); } }
方案说明
- 新的
JsonSerializerOptions完全复制原配置,仅移除当前的AnimalCallbacksConverter,因此调用Deserialize时会使用框架默认的反序列化逻辑,不会再次触发递归。 - 既不用手动实现完整的反序列化逻辑,又能在反序列化前后插入自定义代码,完全匹配你的需求。
内容的提问来源于stack exchange,提问作者Chris Phillips
相关产品推荐
相关产品推荐

