Serialization issues with custom IDictionary in MongoDB .NET

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

Still relevant, will anyone answer? Have the same question :slight_smile: