O problema é que o novo driver serializa os dicionários como um documento por padrão.
O driver MongoDB C# tem 3 maneiras de serializar um dicionário:
Document
, ArrayOfArrays
&ArrayOfDocuments
(mais sobre isso nos documentos). Quando ele é serializado como um documento, as chaves do dicionário são os nomes do elemento BSON que possui algumas limitações (por exemplo, como sugere o erro, elas devem ser serializadas como strings). Neste caso, as chaves do dicionário são
DateTime
s que não são serializados como strings, mas como Date
s, então precisamos escolher outro DictionaryRepresentation
. Para alterar a serialização desta propriedade específica podemos usar o
BsonDictionaryOptions
atributo com um DictionaryRepresentation
diferente :[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
public Dictionary<DateTime, int> Dictionary { get; private set; }
No entanto, precisamos fazer isso em cada membro problemático individualmente. Para aplicar esta
DictionaryRepresentation
para todos os membros relevantes, podemos implementar uma nova convenção:class DictionaryRepresentationConvention : ConventionBase, IMemberMapConvention
{
private readonly DictionaryRepresentation _dictionaryRepresentation;
public DictionaryRepresentationConvention(DictionaryRepresentation dictionaryRepresentation)
{
_dictionaryRepresentation = dictionaryRepresentation;
}
public void Apply(BsonMemberMap memberMap)
{
memberMap.SetSerializer(ConfigureSerializer(memberMap.GetSerializer()));
}
private IBsonSerializer ConfigureSerializer(IBsonSerializer serializer)
{
var dictionaryRepresentationConfigurable = serializer as IDictionaryRepresentationConfigurable;
if (dictionaryRepresentationConfigurable != null)
{
serializer = dictionaryRepresentationConfigurable.WithDictionaryRepresentation(_dictionaryRepresentation);
}
var childSerializerConfigurable = serializer as IChildSerializerConfigurable;
return childSerializerConfigurable == null
? serializer
: childSerializerConfigurable.WithChildSerializer(ConfigureSerializer(childSerializerConfigurable.ChildSerializer));
}
}
Que registramos da seguinte forma:
ConventionRegistry.Register(
"DictionaryRepresentationConvention",
new ConventionPack {new DictionaryRepresentationConvention(DictionaryRepresentation.ArrayOfArrays)},
_ => true);