/// <summary> /// Maps a BsonValue to a .NET value. /// </summary> /// <param name="bsonValue">The BsonValue.</param> /// <param name="options">The BsonTypeMapperOptions.</param> /// <returns>The mapped .NET value.</returns> public static object MapToDotNetValue(BsonValue bsonValue, BsonTypeMapperOptions options) { switch (bsonValue.BsonType) { case BsonType.Array: var bsonArray = (BsonArray)bsonValue; if (options.MapBsonArrayTo == typeof(BsonArray)) { return(bsonArray); } else if (options.MapBsonArrayTo == typeof(object[])) { var array = new object[bsonArray.Count]; for (int i = 0; i < bsonArray.Count; i++) { array[i] = MapToDotNetValue(bsonArray[i], options); } return(array); } else if (typeof(IList <object>).IsAssignableFrom(options.MapBsonArrayTo)) { var list = (IList <object>)Activator.CreateInstance(options.MapBsonArrayTo); for (int i = 0; i < bsonArray.Count; i++) { list.Add(MapToDotNetValue(bsonArray[i], options)); } return(list); } else if (typeof(IList).IsAssignableFrom(options.MapBsonArrayTo)) { var list = (IList)Activator.CreateInstance(options.MapBsonArrayTo); for (int i = 0; i < bsonArray.Count; i++) { list.Add(MapToDotNetValue(bsonArray[i], options)); } return(list); } else { var message = string.Format("A BsonArray can't be mapped to a {0}.", BsonUtils.GetFriendlyTypeName(options.MapBsonArrayTo)); throw new NotSupportedException(message); } case BsonType.Binary: #pragma warning disable 618 // about obsolete BsonBinarySubType.OldBinary var bsonBinaryData = (BsonBinaryData)bsonValue; if (bsonBinaryData.SubType == BsonBinarySubType.Binary || bsonBinaryData.SubType == BsonBinarySubType.OldBinary && options.MapOldBinaryToByteArray) { return(bsonBinaryData.Bytes); } else if (bsonBinaryData.SubType == BsonBinarySubType.UuidLegacy || bsonBinaryData.SubType == BsonBinarySubType.UuidStandard) { return(bsonBinaryData.ToGuid()); } else { return(bsonBinaryData); // unmapped } #pragma warning restore 618 case BsonType.Boolean: return(bsonValue.AsBoolean); case BsonType.DateTime: return(bsonValue.AsUniversalTime); case BsonType.Document: var bsonDocument = (BsonDocument)bsonValue; if (options.MapBsonDocumentTo == typeof(BsonDocument)) { return(bsonDocument); } else if (typeof(IDictionary <string, object>).IsAssignableFrom(options.MapBsonDocumentTo)) { var dictionary = (IDictionary <string, object>)Activator.CreateInstance(options.MapBsonDocumentTo); foreach (var element in bsonDocument.Elements) { var mappedValue = MapToDotNetValue(element.Value, options); if (dictionary.ContainsKey(element.Name)) { switch (options.DuplicateNameHandling) { case DuplicateNameHandling.Ignore: break; case DuplicateNameHandling.Overwrite: default: dictionary[element.Name] = mappedValue; break; case DuplicateNameHandling.ThrowException: var message = string.Format("Duplicate element name '{0}'.", element.Name); throw new ArgumentOutOfRangeException(message); } } else { dictionary.Add(element.Name, mappedValue); } } return(dictionary); } else if (typeof(IDictionary).IsAssignableFrom(options.MapBsonDocumentTo)) { var dictionary = (IDictionary)Activator.CreateInstance(options.MapBsonDocumentTo); foreach (var element in bsonDocument.Elements) { var mappedValue = MapToDotNetValue(element.Value, options); if (dictionary.Contains(element.Name)) { switch (options.DuplicateNameHandling) { case DuplicateNameHandling.Ignore: break; case DuplicateNameHandling.Overwrite: default: dictionary[element.Name] = mappedValue; break; case DuplicateNameHandling.ThrowException: var message = string.Format("Duplicate element name '{0}'.", element.Name); throw new ArgumentOutOfRangeException(message); } } else { dictionary.Add(element.Name, mappedValue); } } return(dictionary); } else { var message = string.Format("A BsonDocument can't be mapped to a {0}.", BsonUtils.GetFriendlyTypeName(options.MapBsonArrayTo)); throw new NotSupportedException(message); } case BsonType.Double: return(bsonValue.AsDouble); case BsonType.Int32: return(bsonValue.AsInt32); case BsonType.Int64: return(bsonValue.AsInt64); case BsonType.Null: return(null); // BsonValue.Null maps to C# null case BsonType.ObjectId: return(bsonValue.AsObjectId); case BsonType.String: return(bsonValue.AsString); case BsonType.JavaScript: case BsonType.JavaScriptWithScope: case BsonType.MaxKey: case BsonType.MinKey: case BsonType.RegularExpression: case BsonType.Symbol: case BsonType.Timestamp: case BsonType.Undefined: default: return(bsonValue); // unmapped } }
/// <summary> /// Maps a BsonValue to a .NET value. /// </summary> /// <param name="bsonValue">The BsonValue.</param> /// <param name="options">The BsonTypeMapperOptions.</param> /// <returns>The mapped .NET value.</returns> public static object MapToDotNetValue(BsonValue bsonValue, BsonTypeMapperOptions options) { switch (bsonValue.BsonType) { case BsonType.Array: var bsonArray = (BsonArray)bsonValue; if (options.MapBsonArrayTo == typeof(BsonArray)) { return bsonArray; } else if (options.MapBsonArrayTo == typeof(object[])) { var array = new object[bsonArray.Count]; for (int i = 0; i < bsonArray.Count; i++) { array[i] = MapToDotNetValue(bsonArray[i], options); } return array; } else if (typeof(IList<object>).IsAssignableFrom(options.MapBsonArrayTo)) { var list = (IList<object>)Activator.CreateInstance(options.MapBsonArrayTo); for (int i = 0; i < bsonArray.Count; i++) { list.Add(MapToDotNetValue(bsonArray[i], options)); } return list; } else if (typeof(IList).IsAssignableFrom(options.MapBsonArrayTo)) { var list = (IList)Activator.CreateInstance(options.MapBsonArrayTo); for (int i = 0; i < bsonArray.Count; i++) { list.Add(MapToDotNetValue(bsonArray[i], options)); } return list; } else { var message = string.Format("A BsonArray can't be mapped to a {0}.", BsonUtils.GetFriendlyTypeName(options.MapBsonArrayTo)); throw new NotSupportedException(message); } case BsonType.Binary: #pragma warning disable 618 // about obsolete BsonBinarySubType.OldBinary var bsonBinaryData = (BsonBinaryData)bsonValue; if (bsonBinaryData.SubType == BsonBinarySubType.Binary || bsonBinaryData.SubType == BsonBinarySubType.OldBinary && options.MapOldBinaryToByteArray) { return bsonBinaryData.Bytes; } else if (bsonBinaryData.SubType == BsonBinarySubType.UuidLegacy || bsonBinaryData.SubType == BsonBinarySubType.UuidStandard) { return bsonBinaryData.ToGuid(); } else { return bsonBinaryData; // unmapped } #pragma warning restore 618 case BsonType.Boolean: return bsonValue.AsBoolean; case BsonType.DateTime: return bsonValue.ToUniversalTime(); case BsonType.Document: var bsonDocument = (BsonDocument)bsonValue; if (options.MapBsonDocumentTo == typeof(BsonDocument)) { return bsonDocument; } else if (typeof(IDictionary<string, object>).IsAssignableFrom(options.MapBsonDocumentTo)) { var dictionary = (IDictionary<string, object>)Activator.CreateInstance(options.MapBsonDocumentTo); foreach (var element in bsonDocument.Elements) { var mappedValue = MapToDotNetValue(element.Value, options); if (dictionary.ContainsKey(element.Name)) { switch (options.DuplicateNameHandling) { case DuplicateNameHandling.Ignore: break; case DuplicateNameHandling.Overwrite: default: dictionary[element.Name] = mappedValue; break; case DuplicateNameHandling.ThrowException: var message = string.Format("Duplicate element name '{0}'.", element.Name); throw new ArgumentOutOfRangeException("bsonValue", message); } } else { dictionary.Add(element.Name, mappedValue); } } return dictionary; } else if (typeof(IDictionary).IsAssignableFrom(options.MapBsonDocumentTo)) { var dictionary = (IDictionary)Activator.CreateInstance(options.MapBsonDocumentTo); foreach (var element in bsonDocument.Elements) { var mappedValue = MapToDotNetValue(element.Value, options); if (dictionary.Contains(element.Name)) { switch (options.DuplicateNameHandling) { case DuplicateNameHandling.Ignore: break; case DuplicateNameHandling.Overwrite: default: dictionary[element.Name] = mappedValue; break; case DuplicateNameHandling.ThrowException: var message = string.Format("Duplicate element name '{0}'.", element.Name); throw new ArgumentOutOfRangeException("bsonValue", message); } } else { dictionary.Add(element.Name, mappedValue); } } return dictionary; } else { var message = string.Format("A BsonDocument can't be mapped to a {0}.", BsonUtils.GetFriendlyTypeName(options.MapBsonArrayTo)); throw new NotSupportedException(message); } case BsonType.Double: return bsonValue.AsDouble; case BsonType.Int32: return bsonValue.AsInt32; case BsonType.Int64: return bsonValue.AsInt64; case BsonType.Null: return null; // BsonValue.Null maps to C# null case BsonType.ObjectId: return bsonValue.AsObjectId; case BsonType.String: return bsonValue.AsString; case BsonType.JavaScript: case BsonType.JavaScriptWithScope: case BsonType.MaxKey: case BsonType.MinKey: case BsonType.RegularExpression: case BsonType.Symbol: case BsonType.Timestamp: case BsonType.Undefined: default: return bsonValue; // unmapped } }