BsonClassMapSerializer 已经为 AbstractClassSerializer 注册

Nic*_*ula 3 mongodb-.net-driver

我正在使用 Mongo c# 驱动程序 2.0,并且在为我的 Id 值对象注册 AbstractClassSerializers 时遇到了 BsonSerializer 注册问题。

MongoDB.Bson.BsonSerializationException:已经有一个为 HistoricalEventId 类型注册的序列化程序。

当我查看 BsonSerializer 时,我看到 BsonClassMapSerializer 已经为我的类型注册了。

在此处输入图片说明

我假设正在为我的实体类型创建一个 BsonClassMapSerializer 并且它还为 Id 字段创建一个 BsonClassMapSerializer 。有没有人遇到过这个?如果有帮助,Bson 序列化程序代码如下所示。

抱歉,如果格式错误,c# 似乎不能很好地显示。

HistoricalEventIdBsonSerializer

public class HistoricalEventIdBsonSerializer : ToObjectIdBsonSerializer<HistoricalEventId>
{
    public override HistoricalEventId CreateObjectFromObjectId(ObjectId serializedObj)
    {
        HistoricalEventId parsedObj;
        HistoricalEventId.TryParse(serializedObj, out parsedObj);
        return parsedObj;
    }
}
Run Code Online (Sandbox Code Playgroud)

ToObjectIdBsonSerializer

public abstract class ToObjectIdBsonSerializer<T> : AbstractClassSerializer<T> where T : class
{
    private static readonly Type _convertibleType = typeof(IConvertible<ObjectId>);
    public abstract T CreateObjectFromObjectId(ObjectId serializedObj);

    public override T Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        var bsonType = context.Reader.GetCurrentBsonType();
        ObjectId value;
        switch (bsonType)
        {
            case BsonType.Undefined:
                value = ObjectId.Empty;
                context.Reader.ReadUndefined();
                break;
            case BsonType.Null:
                value = ObjectId.Empty;
                context.Reader.ReadNull();
                break;
            case BsonType.ObjectId:
                value = context.Reader.ReadObjectId();
                break;
            case BsonType.String:
                value = new ObjectId(context.Reader.ReadString());
                break;
            default:
                throw new NotSupportedException("Unable to create the type " + 
                    args.NominalType.Name + " from the bson type " + bsonType + ".");
        }
        return this.CreateObjectFromObjectId(value);
    }

    public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, T value)
    {
        if (value == null)
        {
            context.Writer.WriteObjectId(ObjectId.Empty);
        }
        else
        {
            if (!_convertibleType.IsAssignableFrom(args.NominalType))
            {
                throw new NotSupportedException("The type " + args.NominalType.Name + 
                    " must implement the " + _convertibleType.Name + " interface.");
            }
            var typedObj = (IConvertible<ObjectId>)value;
            context.Writer.WriteObjectId(typedObj.ToValueType());
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

敞篷车

public interface IConvertible<out T>
{
    T ToValueType();
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*ula 7

我的假设一定是正确的,因为我只是通过在创建 MongoClient 和获取数据库之前进行 BsonSerializer 注册来解决这个问题。希望这会帮助别人。