-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Unknown
-
None
-
Affects Version/s: 3.4.0, 3.5.0
-
Component/s: BSON, Serialization
-
None
-
None
-
Dotnet Drivers
-
None
-
None
-
None
-
None
-
None
-
None
Summary
When providing a custom IBsonIdProvider the SetDocumentIdIfMissing method of BsonSerializerExtensions does not currently use the return value and causes and no new ID to be generated if the ID was empty/null.
Please provide the version of the driver:
Found in driver version 3.4.0, appears to still be present after upgrading to 3.5.0
How to Reproduce
Steps to reproduce. If possible, please include a Short, Self Contained, Correct (Compilable), Example.
- Create a new serialization class implementing IBsonIdProvider and register it with the BsonSerializer registry.
- Attached breakpoint at line 29 of BsonSerializerExtensions.cs
- Attempt to serialize/deserialize the class for which the IBsonIdProvider was registered.
- When breakpoint is hit notice that when IBsonIdProvider.GetDocumentId returns false and does not enter the If block to call IBsonIdProvider.GenerateId
Example code, stripped down for brevity
public class DatabaseDocument { public Guid Id { get; set; } public string Name { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; } public abstract class DataBaseDocumentBsonSerializer : IBsonIdProvider { // Invert returns due to a bug in BsonSerializerExtensions SetDocumentIdIfMissing method public bool GetDocumentId(object document, out object id, out Type idNominalType, out IIdGenerator idGenerator) { DatabaseDocument doc = document as DatabaseDocument; ... idNominalType = typeof(Guid); idGenerator = new GuidGenerator(); if (doc.Id == Guid.Empty) { id = null; return false; } id = doc.Id; return true; } public void SetDocumentId(object document, object id) { ... doc.Id = (Guid)id; } } public class DocuemntBsonSerializer : DataBaseDocumentBsonSerializer, IBsonSerializer<DatabaseDocument>{ //IBsonSerializer<DatabaseDocument> implementation } public static void Main(string[] args){ BsonSerializer.RegisterSerializer(typeof(DatabaseDocument), new RecipeBsonSerializer()); //Create MongoClient and get an IMongoCollection<DatabaseDocument> instance collection.InsertOne(new DatabaseDocument()); }
Per the doc on IBsonIdProvider GetDocuementId should return false when no Id is found but SetDocumentIdIfMissing appears to invert this expectation. To my eye it appear that the if statement on line 29 is simply missing an ! to invert the GetDocumentId output.