MongoDB文档反序列化C#对象时referrals属性报错,如何忽略异常文档?
解决MongoDB反序列化部分文档报错的问题
针对你遇到的部分文档中referrals字段类型不匹配(字符串而非List<ObjectId?>)导致的反序列化错误,这里有几个可行的方案:
方案1:查询时先过滤不符合格式的文档
既然问题出在部分文档的referrals是字符串类型,我们可以在查询阶段就把这些文档排除掉。MongoDB支持按字段类型筛选,只保留referrals为数组的文档:
var usersCollection = MongoConnectionHandler.GetDB().GetCollection<User>("users"); // 筛选出referrals字段类型为数组的文档 var filter = Builders<User>.Filter.Type(u => u.referrals, BsonType.Array); var myusers = usersCollection.Find(filter).AsQueryable();
这样遍历的时候就只会处理符合类型要求的文档,直接避开有问题的那些。
方案2:自定义序列化器处理类型不匹配的情况
如果不想丢弃这些文档,而是希望在反序列化时自动处理错误(比如把字符串类型的referrals转为null或空列表),可以给referrals字段自定义一个序列化器:
首先创建自定义序列化器类:
public class NullableObjectIdListSerializer : SerializerBase<List<ObjectId?>> { public override List<ObjectId?> Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args) { var bsonReader = context.Reader; var currentBsonType = bsonReader.GetCurrentBsonType(); // 如果是字符串类型,跳过该值并返回null(也可返回空列表) if (currentBsonType == BsonType.String) { bsonReader.ReadString(); return null; } // 如果是数组,用默认序列化器处理 else if (currentBsonType == BsonType.Array) { var defaultSerializer = new EnumerableInterfaceImplementerSerializer<List<ObjectId?>, ObjectId?>(new NullableSerializer<ObjectId>(new ObjectIdSerializer())); return defaultSerializer.Deserialize(context, args); } // 其他未知类型也跳过并返回null else { bsonReader.SkipValue(); return null; } } public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, List<ObjectId?> value) { // 序列化逻辑沿用默认实现即可 var defaultSerializer = new EnumerableInterfaceImplementerSerializer<List<ObjectId?>, ObjectId?>(new NullableSerializer<ObjectId>(new ObjectIdSerializer())); defaultSerializer.Serialize(context, args, value); } }
然后在User类的referrals字段上应用这个序列化器:
[BsonIgnoreExtraElements] public class User : MongoEntity { [BsonDefaultValue(null)] [BsonSerializer(typeof(NullableObjectIdListSerializer))] public List<ObjectId?> referrals { get; set; } }
这样反序列化时遇到字符串类型的referrals就会自动跳过,不会抛出异常,你可以保留这些文档,只是referrals会被设为null或空列表。
方案3:全局配置错误容忍(谨慎使用)
如果你希望全局处理这类反序列化错误,也可以配置MongoDB驱动的反序列化错误策略,但这种方式会影响所有反序列化操作,可能掩盖其他潜在问题,需谨慎使用:
var settings = new BsonSerializerSettings { IgnoreExtraElements = true, // 遇到反序列化错误时忽略并继续 DeserializationErrorHandling = DeserializationErrorHandling.IgnoreAndContinue }; // 获取集合时指定自定义序列化配置 var users = MongoConnectionHandler.GetDB().GetCollection<User>("users", new MongoCollectionSettings { SerializerRegistry = BsonSerializerRegistry.Create(settings) });
内容的提问来源于stack exchange,提问作者Mohsin Ali
相关产品推荐
相关产品推荐

