diff --git a/src/MongoDB.Bson/Serialization/BsonClassMap.cs b/src/MongoDB.Bson/Serialization/BsonClassMap.cs index 3e257d2259f..2f2810fc369 100644 --- a/src/MongoDB.Bson/Serialization/BsonClassMap.cs +++ b/src/MongoDB.Bson/Serialization/BsonClassMap.cs @@ -1325,12 +1325,14 @@ internal IDiscriminatorConvention GetDiscriminatorConvention() { // it's possible but harmless for multiple threads to do the discriminator convention lookup at the same time discriminatorConvention = LookupDiscriminatorConvention(); - _discriminatorConvention = discriminatorConvention; if (discriminatorConvention != null) { EnsureNoMemberMapConflicts(discriminatorConvention.ElementName); } + + // only cache if validation succeeds + _discriminatorConvention = discriminatorConvention; } return discriminatorConvention; diff --git a/tests/MongoDB.Bson.Tests/Serialization/BsonClassMapTests.cs b/tests/MongoDB.Bson.Tests/Serialization/BsonClassMapTests.cs index 337aae069c6..eedf3b3f302 100644 --- a/tests/MongoDB.Bson.Tests/Serialization/BsonClassMapTests.cs +++ b/tests/MongoDB.Bson.Tests/Serialization/BsonClassMapTests.cs @@ -22,6 +22,7 @@ using MongoDB.Bson.IO; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Bson.Serialization.Conventions; using MongoDB.Bson.TestHelpers; using Xunit; @@ -735,4 +736,33 @@ private class D : C { } } + + public class BsonClassMapGetDiscriminatorConventionTests + { + [Fact] + public void GetDiscriminatorConvention_should_throw_consistently_when_member_conflicts_with_discriminator_element_name() + { + BsonSerializer.RegisterDiscriminatorConvention(typeof(Foo), new FooDiscriminatorConvention()); + + var classMap = new BsonClassMap(); + classMap.AutoMap(); + classMap.Freeze(); + + Assert.Throws(() => classMap.GetDiscriminatorConvention()); + Assert.Throws(() => classMap.GetDiscriminatorConvention()); + } + + private class Foo + { + [BsonElement("type")] + public string Type { get; set; } + } + + private class FooDiscriminatorConvention : IDiscriminatorConvention + { + public string ElementName => "type"; + public Type GetActualType(IBsonReader bsonReader, Type nominalType) => nominalType; + public BsonValue GetDiscriminator(Type nominalType, Type actualType) => nominalType.Name; + } + } }