Problem polega na tym, że nowy sterownik domyślnie serializuje słowniki jako dokument.
Sterownik MongoDB C# ma 3 sposoby serializacji słownika:Document
, ArrayOfArrays
&ArrayOfDocuments
(więcej na ten temat w dokumentach). Kiedy jest serializowany jako dokument, klucze słownika są nazwami elementu BSON, który ma pewne ograniczenia (na przykład, jak sugeruje błąd, muszą być serializowane jako ciągi).
W tym przypadku klucze słownika to DateTime
s, które nie są serializowane jako ciągi, ale jako Date
s więc musimy wybrać inną DictionaryRepresentation
.
Aby zmienić serializację tej konkretnej właściwości, możemy użyć BsonDictionaryOptions
atrybut z inną DictionaryRepresentation
:
[BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)]
public Dictionary<DateTime, int> Dictionary { get; private set; }
Jednak musimy to zrobić na każdym problematycznym członku indywidualnie. Aby zastosować to DictionaryRepresentation
do wszystkich odpowiednich członków możemy wprowadzić nową konwencję:
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));
}
}
Które rejestrujemy w następujący sposób:
ConventionRegistry.Register(
"DictionaryRepresentationConvention",
new ConventionPack {new DictionaryRepresentationConvention(DictionaryRepresentation.ArrayOfArrays)},
_ => true);