.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);
}
}
我正在重构从 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);
}
}