.Net Core MongoDb 驱动程序 - 异常 ReadBsonType 只能在 State 为 Type 时调用,不能在 State 为 Value 时调用

.Net Core MongoDb Driver - Exception ReadBsonType can only be called when State is Type, not when State is Value

我正在重构从 MongoDb 集合中检索文档作为 BsonDocument 的代码。 由于 C# 为我们提供了使用强类型 class 使我们的代码更安全的可能性,我想创建 class 来表示保存在集合中的文档。

我遇到的问题是 属性 应该作为文档保存在集合中,有时,不知何故被保存为空字符串。因此,当 MongoDbDriver 试图反序列化它时,抛出一个异常告诉我它应该是一个嵌套文档而不是一个字符串。

在那种情况下,我想将 属性 值设置为 null

所以我尝试实现我的解串器来解决这种情况:

我的Class:

[BsonIgnoreExtraElements]
public class ExampleModel
{
    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public ObjectId Id { get; set; }

    .
    .
    .

    [BsonElement("usedTemplate")]
    [BsonSerializer(typeof(ExampleModelTemplateSerializer ))]
    public TemplateModel Template { get; set; }
}

序列化器

public class ExampleModelTemplateSerializer : SerializerBase<TemplateModel>
{
    public override TemplateModel Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        return context.Reader.CurrentBsonType == BsonType.String
            ? null 
            : base.Deserialize(context, args);
    }
}

异常

Message: ReadBsonType can only be called when State is Type, not when State is Value.

您收到此错误的原因是您的 context.Reader 无论如何都需要读取字符串,因此您可以调用 context.Reader.ReadString(); 但 return null 如您所愿.

下一个问题是您在 SerializerBase<T> 上调用 base.Deserialize(),这是一个抽象 class,并且将抛出异常(实现 here)。所以你需要通过调用 BsonSerializer:

来处理反序列化
public class ExampleModelTemplateSerializer : SerializerBase<TemplateModel>
{
    public override TemplateModel Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
    {
        if (context.Reader.CurrentBsonType == BsonType.String)
        {
            context.Reader.ReadString();
            return null;
        }

        return BsonSerializer.Deserialize<TemplateModel>(context.Reader);
    }
}