private static Type LookupType(Type nominalType, string typeHint) { Type type = Type.GetType(typeHint); if (type == null) { type = nominalType.Assembly .GetTypes() .FirstOrDefault(t => t.FullName?.EndsWith(typeHint) ?? false); } if (type == null) { type = TypeNameDiscriminator.GetActualType(typeHint); } if (type == null) { type = BsonClassMap .GetRegisteredClassMaps() .SelectMany(x => x.AllMemberMaps) .Where(x => x.MemberType.FullName?.EndsWith(typeHint) ?? false) .Select(x => x.MemberType) .FirstOrDefault(); } if (type != null) { return(type); } throw new InvalidOperationException($"Could not find type for {typeHint}"); }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { if (nominalType == typeof(object)) { var actualType = value.GetType(); bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); bsonWriter.WriteEndDocument(); return; } var items = (Queue)value; var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options); var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions; bsonWriter.WriteStartArray(); foreach (var item in items) { BsonSerializer.Serialize(bsonWriter, typeof(object), item, itemSerializationOptions); } bsonWriter.WriteEndArray(); } }
/// <summary> /// Gets the discriminator. /// </summary> /// <param name="nominalType">Type nominal type.</param> /// <param name="actualType">The actual type.</param> /// <returns>The discriminator (or null if no discriminator is needed).</returns> protected virtual string GetDiscriminator(Type nominalType, Type actualType) { if (nominalType == typeof(object)) { return(TypeNameDiscriminator.GetDiscriminator(actualType)); } return(null); }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { var actualType = value.GetType(); VerifyTypes(nominalType, actualType, typeof(T[, , ])); if (nominalType == typeof(object)) { bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); bsonWriter.WriteEndDocument(); return; } var array = (T[, , ])value; var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options); var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions; bsonWriter.WriteStartArray(); var length1 = array.GetLength(0); var length2 = array.GetLength(1); var length3 = array.GetLength(2); for (int i = 0; i < length1; i++) { bsonWriter.WriteStartArray(); for (int j = 0; j < length2; j++) { bsonWriter.WriteStartArray(); for (int k = 0; k < length3; k++) { BsonSerializer.Serialize(bsonWriter, typeof(T), array[i, j, k], itemSerializationOptions); } bsonWriter.WriteEndArray(); } bsonWriter.WriteEndArray(); } bsonWriter.WriteEndArray(); } }
/// <summary> /// Gets the discriminator. /// </summary> /// <param name="nominalType">Type nominal type.</param> /// <param name="actualType">The actual type.</param> /// <returns>The discriminator (or null if no discriminator is needed).</returns> protected override string GetDiscriminator(Type nominalType, Type actualType) { if (nominalType != actualType) { if (nominalType == typeof(object)) { return(TypeNameDiscriminator.GetDiscriminator(actualType)); } else { return(actualType.Name); } } return(null); }
public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (_trace) { pb.Trace.WriteLine("WebHeaderSerializer.Serialize()"); } if (value == null) { bsonWriter.WriteNull(); } else { if (nominalType == typeof(object)) { var actualType = value.GetType(); bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); // recursive call replacing nominalType with actualType bsonWriter.WriteEndDocument(); return; } var headers = (WebHeaderCollection)value; bsonWriter.WriteStartDocument(); for (int i = 0; i < headers.Count; i++) { bsonWriter.WriteName(headers.GetKey(i)); string[] headerValues = headers.GetValues(i); if (headerValues.Length == 1) { bsonWriter.WriteString(headerValues[0]); } else { bsonWriter.WriteStartArray(); foreach (string headerValue in headerValues) { bsonWriter.WriteString(headerValue); } bsonWriter.WriteEndArray(); } } bsonWriter.WriteEndDocument(); } }
protected object DeserializeState(BsonDocument doc, out string version, out string id) { string t = doc["_t"].AsString; if (string.IsNullOrEmpty(t)) { throw new Exception("No type discriminator in document"); } Type tt = TypeNameDiscriminator.GetActualType(t); if (tt == null) { throw new Exception("Type not found: " + t); } var ret = BsonSerializer.Deserialize(doc, tt); version = doc.Contains("version") ? doc["version"].AsString : null; id = doc.Contains("_id") ? doc["_id"].AsString : null; return(ret); }
protected BsonDocument Serialize(object state, string version, string id) { BsonDocument bd = new BsonDocument(); using (var bw = BsonWriter.Create(bd)) { BsonSerializer.Serialize(bw, state); } string td = TypeNameDiscriminator.GetDiscriminator(state.GetType()); bd["_t"] = td; if (td.Length <= 10) { throw new Exception("Short type name in " + id); } bd["_id"] = id; if (!bd.Contains("version") && version != null) { bd["version"] = version; } return(bd); }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { var actualType = value.GetType(); VerifyTypes(nominalType, actualType, typeof(T[])); if (nominalType == typeof(object)) { bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); bsonWriter.WriteEndDocument(); return; } var array = (T[])value; var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options); var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions; bsonWriter.WriteStartArray(); for (int index = 0; index < array.Length; index++) { BsonSerializer.Serialize(bsonWriter, typeof(T), array[index], itemSerializationOptions); } bsonWriter.WriteEndArray(); } }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { if (nominalType == typeof(object)) { var actualType = value.GetType(); bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); bsonWriter.WriteEndDocument(); return; } var items = ((Stack)value).ToArray(); // convert to array to allow efficient access in reverse order var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options); var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions; // serialize first pushed item first (reverse of enumeration order) bsonWriter.WriteStartArray(); for (var i = items.Length - 1; i >= 0; i--) { BsonSerializer.Serialize(bsonWriter, typeof(object), items[i], itemSerializationOptions); } bsonWriter.WriteEndArray(); } }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { if (nominalType == typeof(object)) { var actualType = value.GetType(); bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); // recursive call replacing nominalType with actualType bsonWriter.WriteEndDocument(); return; } var dictionary = (IDictionary)value; var dictionarySerializationOptions = EnsureSerializationOptions(options); var dictionaryRepresentation = dictionarySerializationOptions.Representation; var keyValuePairSerializationOptions = dictionarySerializationOptions.KeyValuePairSerializationOptions; if (dictionaryRepresentation == DictionaryRepresentation.Dynamic) { dictionaryRepresentation = DictionaryRepresentation.Document; foreach (object key in dictionary.Keys) { var name = key as string; // key might not be a string if (string.IsNullOrEmpty(name) || name[0] == '$' || name.IndexOf('.') != -1 || name.IndexOf('\0') != -1) { dictionaryRepresentation = DictionaryRepresentation.ArrayOfArrays; break; } } } switch (dictionaryRepresentation) { case DictionaryRepresentation.Document: bsonWriter.WriteStartDocument(); foreach (DictionaryEntry dictionaryEntry in dictionary) { bsonWriter.WriteName((string)dictionaryEntry.Key); BsonSerializer.Serialize(bsonWriter, typeof(object), dictionaryEntry.Value, keyValuePairSerializationOptions.ValueSerializationOptions); } bsonWriter.WriteEndDocument(); break; case DictionaryRepresentation.ArrayOfArrays: case DictionaryRepresentation.ArrayOfDocuments: // override KeyValuePair representation if necessary var keyValuePairRepresentation = (dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays) ? BsonType.Array : BsonType.Document; if (keyValuePairSerializationOptions.Representation != keyValuePairRepresentation) { keyValuePairSerializationOptions = new KeyValuePairSerializationOptions( keyValuePairRepresentation, keyValuePairSerializationOptions.KeySerializationOptions, keyValuePairSerializationOptions.ValueSerializationOptions); } bsonWriter.WriteStartArray(); foreach (DictionaryEntry dictionaryEntry in dictionary) { var keyValuePair = new KeyValuePair <object, object>(dictionaryEntry.Key, dictionaryEntry.Value); _keyValuePairSerializer.Serialize( bsonWriter, typeof(KeyValuePair <object, object>), keyValuePair, keyValuePairSerializationOptions); } bsonWriter.WriteEndArray(); break; default: var message = string.Format("'{0}' is not a valid IDictionary representation.", dictionaryRepresentation); throw new BsonSerializationException(message); } } }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { var actualType = value.GetType(); VerifyTypes(nominalType, actualType, typeof(T[, ])); if (nominalType == typeof(object)) { bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); bsonWriter.WriteEndDocument(); return; } var array = (T[, ])value; var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options); var itemSerializationOptions = arraySerializationOptions.ItemSerializationOptions; var itemNominalType = typeof(T); var itemNominalTypeIsValueType = itemNominalType.IsValueType; var itemNominalTypeSerializer = BsonSerializer.LookupSerializer(itemNominalType); var itemDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(itemNominalType); Type lastItemType = null; IBsonSerializer lastItemSerializer = null; // if itemNominalType is a value type then these assignments are final var itemActualType = itemNominalType; var itemActualTypeSerializer = itemNominalTypeSerializer; bsonWriter.WriteStartArray(); var length1 = array.GetLength(0); var length2 = array.GetLength(1); for (int i = 0; i < length1; i++) { bsonWriter.WriteStartArray(); for (int j = 0; j < length2; j++) { var item = array[i, j]; if (!itemNominalTypeIsValueType) { itemActualType = item == null ? itemNominalType : item.GetType(); if (itemActualType == itemNominalType) { itemActualTypeSerializer = itemNominalTypeSerializer; } else if (itemActualType == lastItemType) { itemActualTypeSerializer = lastItemSerializer; } else { itemActualTypeSerializer = BsonSerializer.LookupSerializer(itemActualType); lastItemType = itemActualType; lastItemSerializer = itemActualTypeSerializer; } } itemActualTypeSerializer.Serialize(bsonWriter, itemNominalType, item, itemSerializationOptions); } bsonWriter.WriteEndArray(); } bsonWriter.WriteEndArray(); } }
/// <summary> /// Gets the discriminator value for an actual type. /// </summary> /// <param name="nominalType">The nominal type.</param> /// <param name="actualType">The actual type.</param> /// <returns>The discriminator value.</returns> public BsonValue GetDiscriminator(Type nominalType, Type actualType) { return(TypeNameDiscriminator.GetDiscriminator(actualType)); }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { if (nominalType == typeof(object)) { var actualType = value.GetType(); bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); // recursive call replacing nominalType with actualType bsonWriter.WriteEndDocument(); return; } var dictionary = (IDictionary <TKey, TValue>)value; var dictionarySerializationOptions = EnsureSerializationOptions(options); var dictionaryRepresentation = dictionarySerializationOptions.Representation; var keyValuePairSerializationOptions = dictionarySerializationOptions.KeyValuePairSerializationOptions; if (dictionaryRepresentation == DictionaryRepresentation.Dynamic) { if (typeof(TKey) == typeof(string) || typeof(TKey) == typeof(object)) { dictionaryRepresentation = DictionaryRepresentation.Document; foreach (object key in dictionary.Keys) { var name = key as string; // check for null and type string at the same time if (name == null || name[0] == '$' || name.IndexOf('.') != -1) { dictionaryRepresentation = DictionaryRepresentation.ArrayOfArrays; break; } } } else { dictionaryRepresentation = DictionaryRepresentation.ArrayOfArrays; } } switch (dictionaryRepresentation) { case DictionaryRepresentation.Document: bsonWriter.WriteStartDocument(); foreach (var keyValuePair in dictionary) { bsonWriter.WriteName((string)(object)keyValuePair.Key); BsonSerializer.Serialize(bsonWriter, typeof(TValue), keyValuePair.Value, keyValuePairSerializationOptions.ValueSerializationOptions); } bsonWriter.WriteEndDocument(); break; case DictionaryRepresentation.ArrayOfArrays: case DictionaryRepresentation.ArrayOfDocuments: // override KeyValuePair representation if necessary var keyValuePairRepresentation = (dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays) ? BsonType.Array : BsonType.Document; if (keyValuePairSerializationOptions.Representation != keyValuePairRepresentation) { keyValuePairSerializationOptions = new KeyValuePairSerializationOptions( keyValuePairRepresentation, keyValuePairSerializationOptions.KeySerializationOptions, keyValuePairSerializationOptions.ValueSerializationOptions); } bsonWriter.WriteStartArray(); foreach (var keyValuePair in dictionary) { _keyValuePairSerializer.Serialize( bsonWriter, typeof(KeyValuePair <TKey, TValue>), keyValuePair, keyValuePairSerializationOptions); } bsonWriter.WriteEndArray(); break; default: var message = string.Format("'{0}' is not a valid IDictionary<{1}, {2}> representation.", dictionaryRepresentation, BsonUtils.GetFriendlyTypeName(typeof(TKey)), BsonUtils.GetFriendlyTypeName(typeof(TValue))); throw new BsonSerializationException(message); } } }
//private KeyValuePair<string, string> DeserializeNameValue(BsonReader bsonReader) //{ // string key = null; // string value = null; // var bsonType = bsonReader.GetCurrentBsonType(); // if (bsonType == BsonType.Array) // { // // [["toto1", "tata1"], ["toto2", "tata2"]] // bsonReader.ReadStartArray(); // //bsonReader.ReadBsonType(); // //var keyType = keyDiscriminatorConvention.GetActualType(bsonReader, typeof(TKey)); // //var keySerializer = GetKeySerializer(keyType); // //key = (TKey)keySerializer.Deserialize(bsonReader, typeof(TKey), keyType, keyValuePairSerializationOptions.KeySerializationOptions); // //bsonReader.ReadBsonType(); // //var valueType = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(TValue)); // //var valueSerializer = GetValueSerializer(valueType); // //value = (TValue)valueSerializer.Deserialize(bsonReader, typeof(TValue), valueType, keyValuePairSerializationOptions.ValueSerializationOptions); // key = bsonReader.ReadString(); // value = bsonReader.ReadString(); // bsonReader.ReadEndArray(); // } // else if (bsonType == BsonType.Document) // { // // [{ "k" : "toto1", "v" : "tata1" }, { "k" : "toto2", "v" : "tata2" }] // bsonReader.ReadStartDocument(); // var bsonTrie = new BsonTrie<bool>(); // bsonTrie.Add("k", true); // is key // bsonTrie.Add("v", false); // bool keyFound = false, valueFound = false; // bool elementFound; // bool elementIsKey; // while (bsonReader.ReadBsonType(bsonTrie, out elementFound, out elementIsKey) != BsonType.EndOfDocument) // { // var name = bsonReader.ReadName(); // if (elementFound) // { // if (elementIsKey) // { // //var keyType = keyDiscriminatorConvention.GetActualType(bsonReader, typeof(TKey)); // //var keySerializer = GetValueSerializer(keyType); // //key = (TKey)keySerializer.Deserialize(bsonReader, typeof(TKey), keyType, keyValuePairSerializationOptions.KeySerializationOptions); // key = bsonReader.ReadString(); // keyFound = true; // } // else // { // //var valueType = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(TValue)); // //var valueSerializer = GetValueSerializer(valueType); // //value = (TValue)valueSerializer.Deserialize(bsonReader, typeof(TValue), valueType, keyValuePairSerializationOptions.ValueSerializationOptions); // value = bsonReader.ReadString(); // valueFound = true; // } // } // else // { // var message = string.Format("Element '{0}' is not valid for KeyValuePairs (expecting 'k' or 'v').", name); // throw new BsonSerializationException(message); // } // } // bsonReader.ReadEndDocument(); // if (!keyFound) // { // //throw new FileFormatException("KeyValuePair item was missing the 'k' element."); // throw new PBException("KeyValuePair item was missing the 'k' element."); // } // if (!valueFound) // { // //throw new FileFormatException("KeyValuePair item was missing the 'v' element."); // throw new PBException("KeyValuePair item was missing the 'v' element."); // } // } // else // { // //var message = string.Format("Cannot deserialize '{0}' from BsonType {1}.", BsonUtils.GetFriendlyTypeName(typeof(KeyValuePair<string, string>)), bsonType); // //throw new FileFormatException(message); // throw new PBException("Cannot deserialize '{0}' from BsonType {1}.", BsonUtils.GetFriendlyTypeName(typeof(KeyValuePair<string, string>)), bsonType); // } // return new KeyValuePair<string, string>(key, value); //} /// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (_trace) { pb.Trace.WriteLine("NameValueCollectionSerializer.Serialize()"); } if (value == null) { bsonWriter.WriteNull(); } else { // dont know why nominalType can be an object if (nominalType == typeof(object)) { var actualType = value.GetType(); bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); // recursive call replacing nominalType with actualType bsonWriter.WriteEndDocument(); return; } // json Dictionary // { "toto1" : "tata1", "toto2" : "tata2" } //var dictionary = (IDictionary)value; NameValueCollection nameValueCollection = (NameValueCollection)value; var dictionarySerializationOptions = EnsureSerializationOptions(options); var dictionaryRepresentation = dictionarySerializationOptions.Representation; var keyValuePairSerializationOptions = dictionarySerializationOptions.KeyValuePairSerializationOptions; if (dictionaryRepresentation == DictionaryRepresentation.Dynamic) { // if some keys contain '$', '.' or '\0' serialize as ArrayOfArrays otherwise serialize as Document dictionaryRepresentation = DictionaryRepresentation.Document; foreach (string key in nameValueCollection.Keys) { //var name = key as string; // key might not be a string if (string.IsNullOrEmpty(key) || key[0] == '$' || key.IndexOf('.') != -1 || key.IndexOf('\0') != -1) { dictionaryRepresentation = DictionaryRepresentation.ArrayOfArrays; break; } } } switch (dictionaryRepresentation) { case DictionaryRepresentation.Document: bsonWriter.WriteStartDocument(); //foreach (DictionaryEntry dictionaryEntry in dictionary) //{ // bsonWriter.WriteName((string)dictionaryEntry.Key); // BsonSerializer.Serialize(bsonWriter, typeof(object), dictionaryEntry.Value, keyValuePairSerializationOptions.ValueSerializationOptions); //} for (int i = 0; i < nameValueCollection.Count; i++) { bsonWriter.WriteString(nameValueCollection.GetKey(i), nameValueCollection.Get(i)); } bsonWriter.WriteEndDocument(); break; case DictionaryRepresentation.ArrayOfArrays: case DictionaryRepresentation.ArrayOfDocuments: // override KeyValuePair representation if necessary var keyValuePairRepresentation = (dictionaryRepresentation == DictionaryRepresentation.ArrayOfArrays) ? BsonType.Array : BsonType.Document; if (keyValuePairSerializationOptions.Representation != keyValuePairRepresentation) { keyValuePairSerializationOptions = new KeyValuePairSerializationOptions(keyValuePairRepresentation, keyValuePairSerializationOptions.KeySerializationOptions, keyValuePairSerializationOptions.ValueSerializationOptions); } bsonWriter.WriteStartArray(); //foreach (DictionaryEntry dictionaryEntry in dictionary) for (int i = 0; i < nameValueCollection.Count; i++) { //var keyValuePair = new KeyValuePair<object, object>(dictionaryEntry.Key, dictionaryEntry.Value); var keyValuePair = new KeyValuePair <string, string>(nameValueCollection.GetKey(i), nameValueCollection.Get(i)); //_keyValuePairSerializer.Serialize(bsonWriter, typeof(KeyValuePair<object, object>), keyValuePair, keyValuePairSerializationOptions); _keyValuePairSerializer.Serialize(bsonWriter, typeof(KeyValuePair <string, string>), keyValuePair, keyValuePairSerializationOptions); } bsonWriter.WriteEndArray(); //bsonWriter.WriteStartArray(); //for (int i = 0; i < nameValueCollection.Count; i++) //{ // bsonWriter.WriteStartArray(); // bsonWriter.WriteString(nameValueCollection.GetKey(i), nameValueCollection.Get(i)); // bsonWriter.WriteEndArray(); //} //bsonWriter.WriteEndArray(); break; //case DictionaryRepresentation.ArrayOfDocuments: // bsonWriter.WriteStartArray(); // for (int i = 0; i < nameValueCollection.Count; i++) // { // bsonWriter.WriteStartDocument(); // bsonWriter.WriteString(nameValueCollection.GetKey(i), nameValueCollection.Get(i)); // bsonWriter.WriteEndDocument(); // } // bsonWriter.WriteEndArray(); // break; default: var message = string.Format("'{0}' is not a valid IDictionary representation.", dictionaryRepresentation); throw new BsonSerializationException(message); } } }
/// <summary> /// Serializes an object to a BsonWriter. /// </summary> /// <param name="bsonWriter">The BsonWriter.</param> /// <param name="nominalType">The nominal type.</param> /// <param name="value">The object.</param> /// <param name="options">The serialization options.</param> public override void Serialize( BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options) { if (value == null) { bsonWriter.WriteNull(); } else { if (nominalType == typeof(object)) { var actualType = value.GetType(); bsonWriter.WriteStartDocument(); bsonWriter.WriteString("_t", TypeNameDiscriminator.GetDiscriminator(actualType)); bsonWriter.WriteName("_v"); Serialize(bsonWriter, actualType, value, options); // recursive call replacing nominalType with actualType bsonWriter.WriteEndDocument(); return; } // support RepresentationSerializationOptions for backward compatibility var representationSerializationOptions = options as RepresentationSerializationOptions; if (representationSerializationOptions != null) { switch (representationSerializationOptions.Representation) { case BsonType.Array: options = DictionarySerializationOptions.ArrayOfArrays; break; case BsonType.Document: options = DictionarySerializationOptions.Document; break; default: var message = string.Format("BsonType {0} is not a valid representation for a Dictionary.", representationSerializationOptions.Representation); throw new BsonSerializationException(message); } } var dictionary = (IDictionary <TKey, TValue>)value; var dictionarySerializationOptions = EnsureSerializationOptions <DictionarySerializationOptions>(options); var representation = dictionarySerializationOptions.Representation; var itemSerializationOptions = dictionarySerializationOptions.ItemSerializationOptions; if (representation == DictionaryRepresentation.Dynamic) { if (typeof(TKey) == typeof(string) || typeof(TKey) == typeof(object)) { representation = DictionaryRepresentation.Document; foreach (object key in dictionary.Keys) { var name = key as string; // check for null and type string at the same time if (name == null || name[0] == '$' || name.IndexOf('.') != -1) { representation = DictionaryRepresentation.ArrayOfArrays; break; } } } else { representation = DictionaryRepresentation.ArrayOfArrays; } } switch (representation) { case DictionaryRepresentation.Document: bsonWriter.WriteStartDocument(); foreach (KeyValuePair <TKey, TValue> entry in dictionary) { bsonWriter.WriteName((string)(object)entry.Key); BsonSerializer.Serialize(bsonWriter, typeof(TValue), entry.Value, itemSerializationOptions); } bsonWriter.WriteEndDocument(); break; case DictionaryRepresentation.ArrayOfArrays: bsonWriter.WriteStartArray(); foreach (KeyValuePair <TKey, TValue> entry in dictionary) { bsonWriter.WriteStartArray(); BsonSerializer.Serialize(bsonWriter, typeof(TKey), entry.Key); BsonSerializer.Serialize(bsonWriter, typeof(TValue), entry.Value, itemSerializationOptions); bsonWriter.WriteEndArray(); } bsonWriter.WriteEndArray(); break; case DictionaryRepresentation.ArrayOfDocuments: bsonWriter.WriteStartArray(); foreach (KeyValuePair <TKey, TValue> entry in dictionary) { bsonWriter.WriteStartDocument(); bsonWriter.WriteName("k"); BsonSerializer.Serialize(bsonWriter, typeof(TKey), entry.Key); bsonWriter.WriteName("v"); BsonSerializer.Serialize(bsonWriter, typeof(TValue), entry.Value, itemSerializationOptions); bsonWriter.WriteEndDocument(); } bsonWriter.WriteEndArray(); break; default: var message = string.Format( "'{0}' is not a valid {1} representation.", representation, BsonUtils.GetFriendlyTypeName(typeof(IDictionary <TKey, TValue>))); throw new BsonSerializationException(message); } } }