Uploaded image for project: 'C# Driver'
  1. C# Driver
  2. CSHARP-4587

ArgumentException using custom Dictionary serializer with IReadOnlyDictionary in a projection after upgrading to 2.19 driver

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: LINQ3
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?

      Summary

      We're using a custom IBsonSerializationProvider that provides a custom serializer/deserializer for string dictionary keys.

      After upgrading to the 2.19 (and 2.19.1) driver with the LINQ3 provider enabled by default, our projections containing IReadOnlyDictionary<string, string> get an ArgumentException.

       

      Tested against a standalone 5.0.15 server.

       

      How to Reproduce

      [^ConsoleApp1.zip]

      The attached example includes the connection string and name of the database as arguments in the launchSettings.json. The relevant parts are:

       

      BsonSerializer.RegisterSerializationProvider(new KeyEncodingDictionarySerializationProvider());
      // <snip>
      await collection.Find(filter)
          .Project(Builders<Model>.Projection.Expression(
              m => new Model(m.Id)
              {
                  Properties = m.Properties,
              }))
          .SingleAsync();

      Where the Model class has a property named Properties of type IReadOnlyDictionary<string, string> and the KeyEncodingDictionarySerializationProvider creates an IBsonSerializer of type DictionarySerializerBase<Dictionary<string, string>?, string, string>.

      The result is an ArgumentException (edited a little to reduce verbosity):

      Value type of serializer is Dictionary`2[[System.String],[System.String]] and does not match member type IReadOnlyDictionary`2[[System.String],[System.String]]. (Parameter 'serializer')
        Source=MongoDB.Bson
        StackTrace:
         at MongoDB.Bson.Serialization.BsonMemberMap.SetSerializer(IBsonSerializer serializer)
         at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.MemberInitExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, MemberInitExpression expression)
         at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, Expression expression)
         at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(TranslationContext context, LambdaExpression lambdaExpression, IBsonSerializer parameterSerializer, Boolean asRoot)
         at MongoDB.Driver.Linq.Linq3Implementation.LinqProviderAdapterV3.TranslateExpressionToProjection[TInput,TOutput](Expression`1 expression, IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions)
         at MongoDB.Driver.Linq.Linq3Implementation.LinqProviderAdapterV3.TranslateExpressionToFindProjection[TSource,TProjection](Expression`1 expression, IBsonSerializer`1 sourceSerializer, IBsonSerializerRegistry serializerRegistry)
         at MongoDB.Driver.FindExpressionProjectionDefinition`2.Render(IBsonSerializer`1 sourceSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider)
         at MongoDB.Driver.MongoCollectionImpl`1.CreateFindOperation[TProjection](FilterDefinition`1 filter, FindOptions`2 options)
         at MongoDB.Driver.MongoCollectionImpl`1.FindAsync[TProjection](IClientSessionHandle session, FilterDefinition`1 filter, FindOptions`2 options, CancellationToken cancellationToken)
         at MongoDB.Driver.MongoCollectionImpl`1.<>c__DisplayClass48_0`1.<FindAsync>b__0(IClientSessionHandle session)
         at MongoDB.Driver.MongoCollectionImpl`1.<UsingImplicitSessionAsync>d__107`1.MoveNext()
         at MongoDB.Driver.IAsyncCursorSourceExtensions.<SingleAsync>d__11`1.MoveNext()

       

      Additional Background

      We only see the ArgumentException when using projections. Doing inserts and finds without projections works just fine. We ran into this issue after upgrading to the 2.19 driver, presumably because of the switch to the LINQ3 provider by default. Manually switching back to the LINQ2 provider avoids the issue.

            Assignee:
            Unassigned Unassigned
            Reporter:
            paul.spangler@ni.com Paul Spangler
            Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: