-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Unknown
-
None
-
Affects Version/s: 3.5.2
-
Component/s: None
-
None
-
None
-
Dotnet Drivers
-
Not Needed
-
None
-
None
-
None
-
None
-
None
-
None
Summary
BsonClassMap.GetDiscriminatorConvention() performs discriminator/member conflict validation only on first invocation. If the first request throws BsonSerializationException and is caught, all subsequent requests to the same API succeed silently. This creates inconsistent behavior where the same invalid configuration throws on the 1st request but works on the 2nd.
Driver version: MongoDB.Driver 3.5.2
Server version: Any (issue is client-side only)
Topology: N/A
How to Reproduce{}
public abstract class Foo { [BsonId] public ObjectId Id { get; set; } [BsonElement("type")] public abstract string Type { get; } } public class Bar : Foo { public override string Type => "bar"; } public class FooDiscriminatorConvention : IDiscriminatorConvention { public string ElementName => "type"; public Type GetActualType(IBsonReader bsonReader, Type nominalType) => typeof(Bar); public BsonValue GetDiscriminator(Type nominalType, Type actualType) => "bar"; } BsonSerializer.RegisterDiscriminatorConvention(typeof(Foo), new FooDiscriminatorConvention()); var client = new MongoClient("mongodb://localhost:27017"); var collection = client.GetDatabase("test").GetCollection<Foo>("foos"); // 1st request - THROWS BsonSerializationException (correct behavior) try { await collection.Find(FilterDefinition<Foo>.Empty).ToListAsync(); } catch (BsonSerializationException ex) { Console.WriteLine($"1st request threw: {ex.Message}"); } // 2nd request - SUCCEEDS silently (inconsistent behavior!) var results = await collection.Find(FilterDefinition<Foo>.Empty).ToListAsync(); Console.WriteLine($"2nd request succeeded with {results.Count} items");
Additional Background
The problem: The discriminator convention is cached in _discriminatorConvention before EnsureNoMemberMapConflicts() is called. When the validation throws, the convention is already cached. On subsequent calls, _discriminatorConvention is not null, so the validation is skipped entirely.