MongoDB C#驱动2.3版本嵌套字典反序列化问题求助
MongoDB C#驱动2.3版本嵌套字典接口反序列化修复方案
问题根源
升级到2.3驱动后,旧的全局自定义IDiscriminatorConvention会递归处理字典里的IHtmlCompositeBlockItem接口,导致栈溢出。必须针对字典的接口值类型单独配置鉴别逻辑,避免全局递归。
分步解决
1. 编写专属接口鉴别器
只处理IHtmlCompositeBlockItem的类型映射,不要全局套用:
public class HtmlCompositeBlockItemDiscriminator : IDiscriminatorConvention { public string DiscriminatorKey => "_t"; public Type GetActualType(IBsonReader reader, Type nominalType) { // 定位并读取存储的鉴别器字段 var bookmark = reader.GetBookmark(); reader.FindElement(DiscriminatorKey); var typeName = reader.ReadString(); reader.ReturnToBookmark(bookmark); // 按项目中实际实现类型映射,自行补充所有子类 return typeName switch { "HtmlTextBlockItem" => typeof(HtmlTextBlockItem), "HtmlImageBlockItem" => typeof(HtmlImageBlockItem), _ => nominalType }; } public BsonValue GetDiscriminator(Type nominalType, Type actualType) { // 存储类型名称作为鉴别器,和旧数据格式保持一致 return actualType.Name; } }
2. 为字典属性单独配置序列化器
在IHtmlCompositeBlock实现类的映射配置中,给LocalizedItems绑定专用序列化器:
BsonClassMap.RegisterClassMap<YourCompositeBlockImpl>(cm => { cm.AutoMap(); // 针对字典的值类型(IHtmlCompositeBlockItem)配置鉴别器 cm.MapMember(block => block.LocalizedItems) .SetSerializer(new DictionarySerializer<int, IHtmlCompositeBlockItem>( new Int32Serializer(), new InterfaceImplementerSerializer<IHtmlCompositeBlockItem>(new HtmlCompositeBlockItemDiscriminator()) )); });
3. 关键注意事项
- 禁止全局注册鉴别器,否则会触发递归处理字典内的接口对象,直接导致栈溢出
- 确保数据库旧数据中的
_t字段值,和鉴别器里的类型名称完全匹配 InterfaceImplementerSerializer是2.x驱动自带的接口反序列化专用类,比全局鉴别器更精准
验证方法
读取旧数据时,检查是否能正确实例化IHtmlCompositeBlockItem的各个具体子类;写入新数据时,确认_t字段被正确添加到每个字典值对象中。
内容的提问来源于stack exchange,提问作者Damien Doumer
相关产品推荐
相关产品推荐

