コード例 #1
0
        // public methods
        /// <summary>
        /// Deserializes an object from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The BsonReader.</param>
        /// <param name="nominalType">The nominal type of the object.</param>
        /// <param name="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
        {
            var bsonType = bsonReader.CurrentBsonType;

            if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else if (bsonType == BsonType.Array)
            {
                bsonReader.ReadStartArray();
                var list = (nominalType == typeof(List <T>) || nominalType.IsInterface) ? new List <T>() : (ICollection <T>)Activator.CreateInstance(nominalType);
                var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(T));
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(T));
                    var serializer  = BsonSerializer.LookupSerializer(elementType);
                    var element     = (T)serializer.Deserialize(bsonReader, typeof(T), elementType, null);
                    list.Add(element);
                }
                bsonReader.ReadEndArray();
                return(list);
            }
            else
            {
                var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
                throw new FileFormatException(message);
            }
        }
コード例 #2
0
        /// <summary>
        /// Deserializes an object from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The BsonReader.</param>
        /// <param name="nominalType">The nominal type of the object.</param>
        /// <param name="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public override object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            Type actualType, // ignored
            IBsonSerializationOptions options
            )
        {
            var bsonType = bsonReader.CurrentBsonType;

            if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else if (bsonType == BsonType.Array)
            {
                bsonReader.ReadStartArray();
                var list = new ArrayList();
                var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(object));
                    var serializer  = BsonSerializer.LookupSerializer(elementType);
                    var element     = serializer.Deserialize(bsonReader, typeof(object), elementType, null);
                    list.Add(element);
                }
                bsonReader.ReadEndArray();
                return(list);
            }
            else
            {
                var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
                throw new FileFormatException(message);
            }
        }
コード例 #3
0
        /// <summary>
        /// Deserializes an Image from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The BsonReader.</param>
        /// <param name="nominalType">The nominal type of the Image.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An Image.</returns>
        public override object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            IBsonSerializationOptions options
            )
        {
            if (nominalType != typeof(Image))
            {
                var message = string.Format("Nominal type must be Image, not {0}.", nominalType.FullName);
                throw new ArgumentException(message, "nominalType");
            }

            var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(Image));
            var actualType = discriminatorConvention.GetActualType(bsonReader, typeof(Image));

            if (actualType == typeof(Image))
            {
                var message = string.Format("Unable to determine actual type of Image to deserialize.");
                throw new FileFormatException(message);
            }

            var serializer = BsonSerializer.LookupSerializer(actualType);

            return(serializer.Deserialize(bsonReader, nominalType, actualType, options));
        }
コード例 #4
0
 private void DeserializeMember(BsonReader bsonReader, object obj, BsonMemberMap memberMap)
 {
     try
     {
         Type   memberType = memberMap.MemberType;
         Type   actualType = bsonReader.CurrentBsonType != BsonType.Null ? BsonDefaultSerializer.LookupDiscriminatorConvention(memberType).GetActualType(bsonReader, memberType) : memberType;
         object obj1       = memberMap.GetSerializer(actualType).Deserialize(bsonReader, memberType, actualType, memberMap.SerializationOptions);
         // --- Added
         if (IsRelation(memberMap))
         {
             ValidateVirtualRelation(memberMap);
             if (obj1 != null)
             {
                 if (IsReferencesManyRelation(memberMap))
                 {
                     ((IDocument)obj).ReferencesManyIDs[memberMap.MemberName] = ((IEnumerable)obj1).Cast <ObjectId>().ToList();
                 }
                 else
                 {
                     ((IDocument)obj).ReferencesOneIDs[memberMap.MemberName] = (ObjectId)obj1;
                 }
             }
         }
         // --- Added
         else
         {
             memberMap.Setter(obj, obj1);
         }
     }
     catch (Exception ex)
     {
         throw new FileFormatException(string.Format("An error occurred while deserializing the {0} {1} of class {2}: {3}", (object)memberMap.MemberName, memberMap.MemberInfo.MemberType == MemberTypes.Field ? (object)"field" : (object)"property", (object)obj.GetType().FullName, (object)ex.Message), ex);
     }
 }
コード例 #5
0
        /// <summary>
        /// Deserializes an object from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The BsonReader.</param>
        /// <param name="nominalType">The nominal type of the object.</param>
        /// <param name="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public override object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            Type actualType, // ignored
            IBsonSerializationOptions options
            )
        {
            var bsonType = bsonReader.CurrentBsonType;

            if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else if (bsonType == BsonType.Document)
            {
                var dictionary = CreateInstance(nominalType);
                bsonReader.ReadStartDocument();
                var valueDiscriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(TValue));
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var key             = (TKey)(object)bsonReader.ReadName();
                    var valueType       = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(TValue));
                    var valueSerializer = BsonSerializer.LookupSerializer(valueType);
                    var value           = (TValue)valueSerializer.Deserialize(bsonReader, typeof(TValue), valueType, null);
                    dictionary.Add(key, value);
                }
                bsonReader.ReadEndDocument();
                return(dictionary);
            }
            else if (bsonType == BsonType.Array)
            {
                var dictionary = CreateInstance(nominalType);
                bsonReader.ReadStartArray();
                var keyDiscriminatorConvention   = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(TKey));
                var valueDiscriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(TValue));
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    bsonReader.ReadStartArray();
                    bsonReader.ReadBsonType();
                    var keyType       = keyDiscriminatorConvention.GetActualType(bsonReader, typeof(TKey));
                    var keySerializer = BsonSerializer.LookupSerializer(keyType);
                    var key           = (TKey)keySerializer.Deserialize(bsonReader, typeof(TKey), keyType, null);
                    bsonReader.ReadBsonType();
                    var valueType       = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(TValue));
                    var valueSerializer = BsonSerializer.LookupSerializer(valueType);
                    var value           = (TValue)valueSerializer.Deserialize(bsonReader, typeof(TValue), valueType, null);
                    bsonReader.ReadEndArray();
                    dictionary.Add(key, value);
                }
                bsonReader.ReadEndArray();
                return(dictionary);
            }
            else
            {
                var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
                throw new FileFormatException(message);
            }
        }
コード例 #6
0
        protected override Expression VisitTypeIs(TypeBinaryExpression b)
        {
            var convention    = BsonDefaultSerializer.LookupDiscriminatorConvention(b.TypeOperand);
            var discriminator = convention.GetDiscriminator(b.Expression.Type, b.TypeOperand);

            PushElementName(convention.ElementName);
            AddElementWithValue(discriminator);

            return(b);
        }
コード例 #7
0
 public void Serialize(BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
 {
     if (value == null)
     {
         bsonWriter.WriteNull();
     }
     else
     {
         if (nominalType.IsGenericType && nominalType.GetGenericTypeDefinition() == typeof(Nullable <>))
         {
             nominalType = nominalType.GetGenericArguments()[0];
         }
         this.VerifyNominalType(nominalType);
         // Added
         Type type = value == null ? nominalType : ProxyManager.GetUnderlyingType(value);
         // Added
         BsonClassMap bsonClassMap = BsonClassMap.LookupClassMap(type);
         bsonWriter.WriteStartDocument();
         DocumentSerializationOptions serializationOptions = options == null ? DocumentSerializationOptions.Defaults : (DocumentSerializationOptions)options;
         BsonMemberMap memberMap = (BsonMemberMap)null;
         if (serializationOptions.SerializeIdFirst)
         {
             memberMap = bsonClassMap.IdMemberMap;
             if (memberMap != null)
             {
                 this.SerializeMember(bsonWriter, value, memberMap);
             }
         }
         if ((type != nominalType || bsonClassMap.DiscriminatorIsRequired || bsonClassMap.HasRootClass) && !bsonClassMap.IsAnonymous)
         {
             IDiscriminatorConvention discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(nominalType);
             BsonValue discriminator = discriminatorConvention.GetDiscriminator(nominalType, type);
             if (discriminator != (BsonValue)null)
             {
                 bsonWriter.WriteName(discriminatorConvention.ElementName);
                 discriminator.WriteTo(bsonWriter);
             }
         }
         foreach (BsonMemberMap bsonMemberMap in bsonClassMap.MemberMaps)
         {
             if (bsonMemberMap != memberMap)
             {
                 if (bsonMemberMap == bsonClassMap.ExtraElementsMemberMap)
                 {
                     this.SerializeExtraElements(bsonWriter, value, bsonMemberMap);
                 }
                 else
                 {
                     this.SerializeMember(bsonWriter, value, bsonMemberMap);
                 }
             }
         }
         bsonWriter.WriteEndDocument();
     }
 }
コード例 #8
0
        /// <summary>
        /// Deserializes an object from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The BsonReader.</param>
        /// <param name="nominalType">The nominal type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            IBsonSerializationOptions options
            )
        {
            if (nominalType != typeof(object))
            {
                var message = string.Format("ObjectSerializer can only be used with nominal type System.Object, not type {1}.", nominalType.FullName);
                throw new InvalidOperationException(message);
            }

            var bsonType = bsonReader.CurrentBsonType;

            if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else if (bsonType == BsonType.Document)
            {
                var bookmark = bsonReader.GetBookmark();
                bsonReader.ReadStartDocument();
                if (bsonReader.ReadBsonType() == BsonType.EndOfDocument)
                {
                    bsonReader.ReadEndDocument();
                    return(new object());
                }
                else
                {
                    bsonReader.ReturnToBookmark(bookmark);
                }
            }

            var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
            var actualType = discriminatorConvention.GetActualType(bsonReader, typeof(object));

            if (actualType == typeof(object))
            {
                var message = string.Format("Unable to determine actual type of object to deserialize. NominalType is System.Object and BsonType is {0}.", bsonType);
                throw new FileFormatException(message);
            }

            var serializer = BsonSerializer.LookupSerializer(actualType);

            return(serializer.Deserialize(bsonReader, nominalType, actualType, options));
        }
コード例 #9
0
        // public methods
        /// <summary>
        /// Deserializes an object from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The BsonReader.</param>
        /// <param name="nominalType">The nominal type of the object.</param>
        /// <param name="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public override object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            Type actualType,
            IBsonSerializationOptions options)
        {
            var bsonType = bsonReader.GetCurrentBsonType();

            switch (bsonType)
            {
            case BsonType.Null:
                bsonReader.ReadNull();
                return(null);

            case BsonType.Array:
                bsonReader.ReadStartArray();
                var stack = new Stack <T>();
                var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(T));
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var elementType = discriminatorConvention.GetActualType(bsonReader, typeof(T));
                    var serializer  = BsonSerializer.LookupSerializer(elementType);
                    var element     = (T)serializer.Deserialize(bsonReader, typeof(T), elementType, null);
                    stack.Push(element);
                }
                bsonReader.ReadEndArray();
                return(stack);

            case BsonType.Document:
                bsonReader.ReadStartDocument();
                bsonReader.ReadString("_t");     // skip over discriminator
                bsonReader.ReadName("_v");
                var value = Deserialize(bsonReader, actualType, actualType, options);
                bsonReader.ReadEndDocument();
                return(value);

            default:
                var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
                throw new FileFormatException(message);
            }
        }
コード例 #10
0
 public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
 {
     this.VerifyNominalType(nominalType);
     if (bsonReader.CurrentBsonType == BsonType.Null)
     {
         bsonReader.ReadNull();
         return((object)null);
     }
     else
     {
         Type actualType = BsonDefaultSerializer.LookupDiscriminatorConvention(nominalType).GetActualType(bsonReader, nominalType);
         if (actualType != nominalType)
         {
             IBsonSerializer bsonSerializer = BsonSerializer.LookupSerializer(actualType);
             if (bsonSerializer != this)
             {
                 return(bsonSerializer.Deserialize(bsonReader, nominalType, actualType, options));
             }
         }
         return(this.Deserialize(bsonReader, nominalType, actualType, options));
     }
 }
コード例 #11
0
        // public methods
        /// <summary>
        /// Deserializes an object from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The BsonReader.</param>
        /// <param name="nominalType">The nominal type of the object.</param>
        /// <param name="actualType">The actual type of the object.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>An object.</returns>
        public override object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
        {
            var bsonType = bsonReader.CurrentBsonType;

            if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                return(null);
            }
            else if (bsonType == BsonType.Document)
            {
                if (nominalType == typeof(object))
                {
                    bsonReader.ReadStartDocument();
                    bsonReader.ReadString("_t");                              // skip over discriminator
                    bsonReader.ReadName("_v");
                    var value = Deserialize(bsonReader, actualType, options); // recursive call replacing nominalType with actualType
                    bsonReader.ReadEndDocument();
                    return(value);
                }

                var dictionary = CreateInstance(nominalType);
                bsonReader.ReadStartDocument();
                var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var key             = bsonReader.ReadName();
                    var valueType       = discriminatorConvention.GetActualType(bsonReader, typeof(object));
                    var valueSerializer = BsonSerializer.LookupSerializer(valueType);
                    var value           = valueSerializer.Deserialize(bsonReader, typeof(object), valueType, null);
                    dictionary.Add(key, value);
                }
                bsonReader.ReadEndDocument();
                return(dictionary);
            }
            else if (bsonType == BsonType.Array)
            {
                var dictionary = CreateInstance(nominalType);
                bsonReader.ReadStartArray();
                var discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(typeof(object));
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    if (bsonReader.CurrentBsonType == BsonType.Array)
                    {
                        bsonReader.ReadStartArray();
                        bsonReader.ReadBsonType();
                        var keyType       = discriminatorConvention.GetActualType(bsonReader, typeof(object));
                        var keySerializer = BsonSerializer.LookupSerializer(keyType);
                        var key           = keySerializer.Deserialize(bsonReader, typeof(object), keyType, null);
                        bsonReader.ReadBsonType();
                        var valueType       = discriminatorConvention.GetActualType(bsonReader, typeof(object));
                        var valueSerializer = BsonSerializer.LookupSerializer(valueType);
                        var value           = valueSerializer.Deserialize(bsonReader, typeof(object), valueType, null);
                        bsonReader.ReadEndArray();
                        dictionary.Add(key, value);
                    }
                    else if (bsonReader.CurrentBsonType == BsonType.Document)
                    {
                        bsonReader.ReadStartDocument();
                        object key = null;
                        object value = null;
                        bool   keyFound = false, valueFound = false;
                        while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                        {
                            var name = bsonReader.ReadName();
                            switch (name)
                            {
                            case "k":
                                var keyType       = discriminatorConvention.GetActualType(bsonReader, typeof(object));
                                var keySerializer = BsonSerializer.LookupSerializer(keyType);
                                key      = keySerializer.Deserialize(bsonReader, typeof(object), keyType, null);
                                keyFound = true;
                                break;

                            case "v":
                                var valueType       = discriminatorConvention.GetActualType(bsonReader, typeof(object));
                                var valueSerializer = BsonSerializer.LookupSerializer(valueType);
                                value      = valueSerializer.Deserialize(bsonReader, typeof(object), valueType, null);
                                valueFound = true;
                                break;

                            default:
                                var message = string.Format("Element '{0}' is not valid for Dictionary items (expecting 'k' or 'v').", name);
                                throw new FileFormatException(message);
                            }
                        }
                        bsonReader.ReadEndDocument();
                        if (!keyFound)
                        {
                            throw new FileFormatException("Dictionary item was missing the 'k' element.");
                        }
                        if (!valueFound)
                        {
                            throw new FileFormatException("Dictionary item was missing the 'v' element.");
                        }
                        dictionary.Add(key, value);
                    }
                    else
                    {
                        var message = string.Format("Expected document or array for Dictionary item, not {0}.", bsonReader.CurrentBsonType);
                        throw new FileFormatException(message);
                    }
                }
                bsonReader.ReadEndArray();
                return(dictionary);
            }
            else
            {
                var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
                throw new FileFormatException(message);
            }
        }
コード例 #12
0
        /// <summary>
        /// Gets the actual type of an object by reading the discriminator from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The reader.</param>
        /// <param name="nominalType">The nominal type.</param>
        /// <returns>The actual type.</returns>
        public Type GetActualType(
            BsonReader bsonReader,
            Type nominalType
            )
        {
            // the BsonReader is sitting at the value whose actual type needs to be found
            var bsonType = bsonReader.CurrentBsonType;

            if (bsonReader.State == BsonReaderState.Value)
            {
                Type primitiveType = null;
                switch (bsonType)
                {
                case BsonType.Boolean: primitiveType = typeof(bool); break;

                case BsonType.Binary:
                    var               bookmark = bsonReader.GetBookmark();
                    byte[]            bytes;
                    BsonBinarySubType subType;
                    bsonReader.ReadBinaryData(out bytes, out subType);
                    if (subType == BsonBinarySubType.Uuid && bytes.Length == 16)
                    {
                        primitiveType = typeof(Guid);
                    }
                    bsonReader.ReturnToBookmark(bookmark);
                    break;

                case BsonType.DateTime: primitiveType = typeof(DateTime); break;

                case BsonType.Double: primitiveType = typeof(double); break;

                case BsonType.Int32: primitiveType = typeof(int); break;

                case BsonType.Int64: primitiveType = typeof(long); break;

                case BsonType.ObjectId: primitiveType = typeof(ObjectId); break;

                case BsonType.String: primitiveType = typeof(string); break;
                }

                if (primitiveType != null && nominalType.IsAssignableFrom(primitiveType))
                {
                    return(primitiveType);
                }
            }

            if (bsonType == BsonType.Document)
            {
                var bookmark = bsonReader.GetBookmark();
                bsonReader.ReadStartDocument();
                var actualType = nominalType;
                if (bsonReader.FindElement(elementName))
                {
                    var discriminator = BsonValue.ReadFrom(bsonReader);
                    if (discriminator.IsBsonArray)
                    {
                        discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator
                    }
                    actualType = BsonDefaultSerializer.LookupActualType(nominalType, discriminator);
                }
                bsonReader.ReturnToBookmark(bookmark);
                return(actualType);
            }

            return(nominalType);
        }
コード例 #13
0
 static BitmapSerializer()
 {
     BsonDefaultSerializer.RegisterDiscriminator(typeof(Bitmap), "Bitmap");
 }
コード例 #14
0
 static A()
 {
     BsonDefaultSerializer.RegisterDiscriminatorConvention(typeof(A), new MagicDiscriminatorConvention());
 }
コード例 #15
0
        /// <summary>
        /// Gets the actual type of an object by reading the discriminator from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The reader.</param>
        /// <param name="nominalType">The nominal type.</param>
        /// <returns>The actual type.</returns>
        public Type GetActualType(
            BsonReader bsonReader,
            Type nominalType
            )
        {
            // the BsonReader is sitting at the value whose actual type needs to be found
            var bsonType = bsonReader.CurrentBsonType;

            if (bsonReader.State == BsonReaderState.Value)
            {
                Type primitiveType = null;
                switch (bsonType)
                {
                case BsonType.Boolean: primitiveType = typeof(bool); break;

                case BsonType.Binary:
                    var               bookmark = bsonReader.GetBookmark();
                    byte[]            bytes;
                    BsonBinarySubType subType;
                    bsonReader.ReadBinaryData(out bytes, out subType);
                    if (subType == BsonBinarySubType.UuidStandard || subType == BsonBinarySubType.UuidLegacy)
                    {
                        primitiveType = typeof(Guid);
                    }
                    bsonReader.ReturnToBookmark(bookmark);
                    break;

                case BsonType.DateTime: primitiveType = typeof(DateTime); break;

                case BsonType.Double: primitiveType = typeof(double); break;

                case BsonType.Int32: primitiveType = typeof(int); break;

                case BsonType.Int64: primitiveType = typeof(long); break;

                case BsonType.ObjectId: primitiveType = typeof(ObjectId); break;

                case BsonType.String: primitiveType = typeof(string); break;
                }

                if (primitiveType != null && nominalType.IsAssignableFrom(primitiveType))
                {
                    return(primitiveType);
                }
            }

            if (bsonType == BsonType.Document)
            {
                // ensure KnownTypes of nominalType are registered (so IsTypeDiscriminated returns correct answer)
                BsonDefaultSerializer.EnsureKnownTypesAreRegistered(nominalType);

                // we can skip looking for a discriminator if nominalType has no discriminated sub types
                if (BsonDefaultSerializer.IsTypeDiscriminated(nominalType))
                {
                    var bookmark = bsonReader.GetBookmark();
                    bsonReader.ReadStartDocument();
                    var actualType = nominalType;
                    if (bsonReader.FindElement(elementName))
                    {
                        var discriminator = BsonValue.ReadFrom(bsonReader);
                        if (discriminator.IsBsonArray)
                        {
                            discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator
                        }
                        actualType = BsonDefaultSerializer.LookupActualType(nominalType, discriminator);
                    }
                    bsonReader.ReturnToBookmark(bookmark);
                    return(actualType);
                }
            }

            return(nominalType);
        }
コード例 #16
0
 public object Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
 {
     this.VerifyNominalType(nominalType);
     if (bsonReader.CurrentBsonType == BsonType.Null)
     {
         bsonReader.ReadNull();
         return((object)null);
     }
     else
     {
         if (actualType.IsValueType)
         {
             throw new BsonSerializationException(string.Format("Value class {0} cannot be deserialized.", (object)actualType.FullName));
         }
         BsonClassMap bsonClassMap = BsonClassMap.LookupClassMap(actualType);
         if (bsonClassMap.IsAnonymous)
         {
             throw new InvalidOperationException("An anonymous class cannot be deserialized.");
         }
         // Added
         object instance = CreateInstance(bsonClassMap);
         // Added
         if (bsonReader.CurrentBsonType != BsonType.Document)
         {
             throw new FileFormatException(string.Format("Expected a nested document representing the serialized form of a {0} value, but found a value of type {1} instead.", (object)actualType.FullName, (object)bsonReader.CurrentBsonType));
         }
         bsonReader.ReadStartDocument();
         HashSet <BsonMemberMap>  hashSet = new HashSet <BsonMemberMap>(bsonClassMap.MemberMaps);
         IDiscriminatorConvention discriminatorConvention = BsonDefaultSerializer.LookupDiscriminatorConvention(nominalType);
         while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
         {
             string elementName = bsonReader.ReadName();
             if (elementName == discriminatorConvention.ElementName)
             {
                 bsonReader.SkipValue();
             }
             else
             {
                 BsonMemberMap memberMapForElement = bsonClassMap.GetMemberMapForElement(elementName);
                 if (memberMapForElement != null && memberMapForElement != bsonClassMap.ExtraElementsMemberMap)
                 {
                     this.DeserializeMember(bsonReader, instance, memberMapForElement);
                     hashSet.Remove(memberMapForElement);
                 }
                 else if (bsonClassMap.ExtraElementsMemberMap != null)
                 {
                     this.DeserializeExtraElement(bsonReader, instance, elementName, bsonClassMap.ExtraElementsMemberMap);
                 }
                 else
                 {
                     if (!bsonClassMap.IgnoreExtraElements)
                     {
                         throw new FileFormatException(string.Format("Element '{0}' does not match any field or property of class {1}.", (object)elementName, (object)bsonClassMap.ClassType.FullName));
                     }
                     bsonReader.SkipValue();
                 }
             }
         }
         bsonReader.ReadEndDocument();
         foreach (BsonMemberMap bsonMemberMap in hashSet)
         {
             if (bsonMemberMap.IsRequired)
             {
                 string str = bsonMemberMap.MemberInfo.MemberType == MemberTypes.Field ? "field" : "property";
                 throw new FileFormatException(string.Format("Required element '{0}' for {1} '{2}' of class {3} is missing.", (object)bsonMemberMap.ElementName, (object)str, (object)bsonMemberMap.MemberName, (object)bsonClassMap.ClassType.FullName));
             }
             else if (bsonMemberMap.HasDefaultValue)
             {
                 bsonMemberMap.ApplyDefaultValue(instance);
             }
         }
         return(instance);
     }
 }