I have a class which implements IDictionary and restricts the type and range of key values. (Basically, a wrapper around a native Dictionary with relevant validation for the key and a fixed key type of Integer, which I have called RestrictedKeyDictionary).
I understand that I cannot serialize as ‘Document’ because my keys are not strings. However, if I choose ArrayOfDocuments or ArrayOfArrays, I still get the same runtime error as if I had chosen Document mode: When using DictionaryRepresentation.Document key values must serialize as strings.
So, either a bug in the driver or more likely the way I am setting the serialization.
In my example below, my member is a RestrictedKeyDictionary(Of String)
, where String is the type of value being stored. Keys are fixed to Integer in the underlying code.
Based on the documentation, I have come up with this serializer (VB.Net):
cm.GetMemberMap(Function(p) p.MyProperty).SetSerializer(New DictionaryInterfaceImplementerSerializer(Of RestrictedKeyDictionary(Of String), Integer, String) _
(Options.DictionaryRepresentation.ArrayOfDocuments))
Note my selection of ArrayOfDocuments here, and despite that, the error message about Document mode. Identical result if I choose ArrayOfArrays.
Does anyone have any thoughts? Also does anyone know of a really good thorough tutorial on serialization for MongoDB .NET? The API documentation, extensive as it is, provides no context for classes, and the reference tutorials fall short in places.
For reference, my entire implementation of RestrictedKeyDictionary here:
Public Class RestrictedKeyDictionary(Of TValue)
Implements IDictionary(Of Integer, TValue)
Private _dct As New Dictionary(Of Integer, TValue)
Private _minkey As Integer
Private _maxkey As Integer
Default Public Property Item(key As Integer) As TValue Implements IDictionary(Of Integer, TValue).Item
Get
Return _dct.Item(key)
End Get
Set(value As TValue)
Add(key, value)
End Set
End Property
Public ReadOnly Property Keys As ICollection(Of Integer) Implements IDictionary(Of Integer, TValue).Keys
Get
Return _dct.Keys
End Get
End Property
Public ReadOnly Property Values As ICollection(Of TValue) Implements IDictionary(Of Integer, TValue).Values
Get
Return _dct.Values
End Get
End Property
Public ReadOnly Property Count As Integer Implements ICollection(Of KeyValuePair(Of Integer, TValue)).Count
Get
Return _dct.Count
End Get
End Property
Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of KeyValuePair(Of Integer, TValue)).IsReadOnly
Get
Return CType(_dct, ICollection(Of KeyValuePair(Of Integer, TValue))).IsReadOnly
End Get
End Property
Public Sub Add(key As Integer, value As TValue) Implements IDictionary(Of Integer, TValue).Add
If key < _minkey Or key > _maxkey Then
Throw New ArgumentOutOfRangeException("key", $"key must be between {_minkey} and {_maxkey}")
Else
_dct.Add(key, value)
End If
End Sub
Public Sub Add(item As KeyValuePair(Of Integer, TValue)) Implements ICollection(Of KeyValuePair(Of Integer, TValue)).Add
Add(item.Key, item.Value)
End Sub
Public Sub Clear() Implements ICollection(Of KeyValuePair(Of Integer, TValue)).Clear
CType(_dct, ICollection(Of KeyValuePair(Of Integer, TValue))).Clear()
End Sub
Public Sub CopyTo(array() As KeyValuePair(Of Integer, TValue), arrayIndex As Integer) Implements ICollection(Of KeyValuePair(Of Integer, TValue)).CopyTo
CType(_dct, ICollection(Of KeyValuePair(Of Integer, TValue))).CopyTo(array, arrayIndex)
End Sub
Public Function ContainsKey(key As Integer) As Boolean Implements IDictionary(Of Integer, TValue).ContainsKey
Return _dct.ContainsKey(key)
End Function
Public Function Remove(key As Integer) As Boolean Implements IDictionary(Of Integer, TValue).Remove
Return _dct.Remove(key)
End Function
Public Function Remove(item As KeyValuePair(Of Integer, TValue)) As Boolean Implements ICollection(Of KeyValuePair(Of Integer, TValue)).Remove
Return CType(_dct, ICollection(Of KeyValuePair(Of Integer, TValue))).Remove(item)
End Function
Public Function TryGetValue(key As Integer, ByRef value As TValue) As Boolean Implements IDictionary(Of Integer, TValue).TryGetValue
Return _dct.TryGetValue(key, value)
End Function
Public Function Contains(item As KeyValuePair(Of Integer, TValue)) As Boolean Implements ICollection(Of KeyValuePair(Of Integer, TValue)).Contains
Return CType(_dct, ICollection(Of KeyValuePair(Of Integer, TValue))).Contains(item)
End Function
Public Function GetEnumerator() As IEnumerator(Of KeyValuePair(Of Integer, TValue)) Implements IEnumerable(Of KeyValuePair(Of Integer, TValue)).GetEnumerator
Return CType(_dct, IEnumerable(Of KeyValuePair(Of Integer, TValue))).GetEnumerator
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return CType(_dct, IEnumerable).GetEnumerator
End Function
Public Sub New(MinKey As Integer, MaxKey As Integer)
_minkey = MinKey
_maxkey = MaxKey
End Sub
End Class