Esempio n. 1
0
        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}");
        }
Esempio n. 2
0
        /// <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();
            }
        }
Esempio n. 3
0
        /// <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();
            }
        }
Esempio n. 5
0
        /// <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);
        }
Esempio n. 6
0
        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();
            }
        }
Esempio n. 10
0
        /// <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();
            }
        }
Esempio n. 11
0
        /// <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);
                }
            }
        }
Esempio n. 12
0
        /// <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));
 }
Esempio n. 14
0
        /// <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);
                }
            }
        }
Esempio n. 16
0
        /// <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);
                }
            }
        }