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

Discriminator conventions don't work properly with generic types

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 2.12.0
    • Component/s: API, BSON, Serialization
    • Environment:
      TargetFramework: .NET 5
      OS: Windows 10
      MongoDB: Community Edition 4.4.3 2008R2Plus SLL (64 bit) - installed as Windows Service

      The default discriminator conventions (ie. HierarchicalDiscriminatorConvention) don't work properly with generic types. Trying to find/insert documents with varying generic types will cause an exception "Ambiguous discriminator 'Type`1'.".

      The problem and solution is also explained in this stackoverflow post: https://stackoverflow.com/questions/25891373/mongodb-c-sharp-driver-type-discriminators-with-generic-class-inheriting-from-no

      The problem seems to be, that the default discriminator conventions use the type's Name property instead of its FullName or AssemblyQualifiedName property.
      For some reason, using FullName will throw an exception: "Unknown discriminator value ...', while AssemblyQualifiedName works.

      This is also what causes this older issue: https://jira.mongodb.org/browse/CSHARP-1240

      The fix for my application was creating a custom discriminator convention that inherits from HierarchicalDiscriminatorConvention and return:

      classMap.ClassType.AssemblyQualifiedName
      

      instead of:

      classMap.Discriminator
      

      inside of the GetDiscriminator method.
      see: https://github.com/mongodb/mongo-csharp-driver/blob/v2.12.x/src/MongoDB.Bson/Serialization/Conventions/HierarchicalDiscriminatorConvention.cs

      Solution/suggestion:

      The problem seems to be, that inside of BsonClassMap.cs, the _discriminator field is assigned a wrong value:

      _discriminator = _classType.Name;
      

      see: https://github.com/mongodb/mongo-csharp-driver/blob/v2.12.x/src/MongoDB.Bson/Serialization/BsonClassMap.cs#L973

      Because of the usage of _classType.Name, the discriminator conventions won't work for generic types.

      A quick fix could be to instead assign AssemblyQualifiedName:

      _discriminator = _classType.AssemblyQualifiedName;
      

      in turn, the default discriminator conventions that access

      classMap.Discriminator
      

      will now receive the correct name.

      I'm not sure why FullName does not work, it should be investigated whether it is better to use it over AssemblyQualifiedName.

            Assignee:
            Unassigned Unassigned
            Reporter:
            inuriasx@gmail.com Raphael Rabl
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: