Problém je v tom, že nový ovladač standardně serializuje slovníky jako dokument.
Ovladač MongoDB C# má 3 způsoby, jak serializovat slovník:Document
, ArrayOfArrays
&ArrayOfDocuments
(více o tom v dokumentech). Když se serializuje jako dokument, klíče slovníku jsou názvy prvku BSON, který má určitá omezení (například, jak naznačuje chyba, musí být serializovány jako řetězce).
V tomto případě jsou klíče slovníku DateTime
s, které nejsou serializovány jako řetězce, ale jako Date
s, takže musíme vybrat jiný DictionaryRepresentation
.
Chcete-li změnit serializaci této specifické vlastnosti, můžeme použít BsonDictionaryOptions
atribut s jiným DictionaryRepresentation
:
[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
public Dictionary<DateTime, int> Dictionary { get; private set; }
To však musíme udělat u každého problematického člena individuálně. Chcete-li použít toto DictionaryRepresentation
všem příslušným členům můžeme zavést novou úmluvu:
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));
}
}
Což registrujeme následovně:
ConventionRegistry.Register(
"DictionaryRepresentationConvention",
new ConventionPack {new DictionaryRepresentationConvention(DictionaryRepresentation.ArrayOfArrays)},
_ => true);