public object Deserialize( BsonReader bsonReader, Type classType ) { // peek at the discriminator (if present) to see what class to create an instance for var discriminator = bsonReader.FindString("_t"); if (discriminator != null) { var actualType = BsonClassMap.LookupTypeByDiscriminator(classType, discriminator); if (!classType.IsAssignableFrom(actualType)) { string message = string.Format("Actual type {0} is not assignable to expected type {1}", actualType.FullName, classType.FullName); throw new FileFormatException(message); } classType = actualType; } var classMap = BsonClassMap.LookupClassMap(classType); if (classMap.IsAnonymous) { throw new InvalidOperationException("Anonymous classes cannot be deserialized"); } var obj = Activator.CreateInstance(classType); var missingElementPropertyMaps = new List<BsonPropertyMap>(classMap.PropertyMaps); // make a copy! bsonReader.ReadStartDocument(); BsonType bsonType; string elementName; while (bsonReader.HasElement(out bsonType, out elementName)) { if (elementName == "_t") { bsonReader.ReadString("_t"); // skip over discriminator continue; } var propertyMap = classMap.GetPropertyMapForElement(elementName); if (propertyMap != null) { propertyMap.PropertySerializer.DeserializeProperty(bsonReader, obj, propertyMap); missingElementPropertyMaps.Remove(propertyMap); } else { if (classMap.IgnoreExtraElements) { bsonReader.SkipElement(); } else { string message = string.Format("Unexpected element: {0}", elementName); throw new FileFormatException(message); } } } bsonReader.ReadEndDocument(); foreach (var propertyMap in missingElementPropertyMaps) { if (propertyMap.IsRequired) { string message = string.Format("Required element is missing: {0}", propertyMap.ElementName); throw new BsonSerializationException(message); } if (propertyMap.HasDefaultValue) { propertyMap.ApplyDefaultValue(obj); } } return obj; }