public void constructor_should_initialize_instance()
        {
            var subject = new ObjectSerializer();

            subject._discriminatorConvention().Should().Be(BsonSerializer.LookupDiscriminatorConvention(typeof(object)));
            subject._guidRepresentation().Should().Be(GuidRepresentation.Unspecified);
        }
        public void Deserialize_binary_data_should_return_expected_result_when_guid_representation_is_specified(
            [ClassValues(typeof(GuidModeValues))]
            GuidMode mode,
            [Values(-1, GuidRepresentation.Unspecified)]
            GuidRepresentation readerGuidRepresentation,
            [Values(GuidRepresentation.CSharpLegacy, GuidRepresentation.JavaLegacy, GuidRepresentation.PythonLegacy, GuidRepresentation.Standard)]
            GuidRepresentation guidRepresentation)
        {
#pragma warning disable 618
            mode.Set();
            var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
            var subject = new ObjectSerializer(discriminatorConvention, guidRepresentation);
            var bytes   = new byte[] { 29, 0, 0, 0, 5, 120, 0, 16, 0, 0, 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0 };
            var subType = GuidConverter.GetSubType(guidRepresentation);
            bytes[11] = (byte)subType;
            var readerSettings = new BsonBinaryReaderSettings();
            if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2)
            {
                readerSettings.GuidRepresentation = readerGuidRepresentation == (GuidRepresentation)(-1) ? guidRepresentation : GuidRepresentation.Unspecified;
            }
            using (var memoryStream = new MemoryStream(bytes))
                using (var reader = new BsonBinaryReader(memoryStream, readerSettings))
                {
                    var context = BsonDeserializationContext.CreateRoot(reader);

                    reader.ReadStartDocument();
                    reader.ReadName("x");
                    var result = subject.Deserialize <object>(context);

                    var guidBytes      = bytes.Skip(12).Take(16).ToArray();
                    var expectedResult = GuidConverter.FromBytes(guidBytes, guidRepresentation);
                    result.Should().Be(expectedResult);
                }
#pragma warning restore 618
        }
        public void Deserialize_binary_data_should_throw_when_guid_representation_is_specified_and_sub_type_is_not_expected_sub_type(
            [ClassValues(typeof(GuidModeValues))]
            GuidMode mode,
            [Values(GuidRepresentation.CSharpLegacy, GuidRepresentation.JavaLegacy, GuidRepresentation.PythonLegacy, GuidRepresentation.Standard)]
            GuidRepresentation readerGuidRepresentation,
            [Values(GuidRepresentation.CSharpLegacy, GuidRepresentation.JavaLegacy, GuidRepresentation.PythonLegacy, GuidRepresentation.Standard)]
            GuidRepresentation guidRepresentation)
        {
#pragma warning disable 618
            mode.Set();
            var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
            var subject          = new ObjectSerializer(discriminatorConvention, guidRepresentation);
            var bytes            = new byte[] { 29, 0, 0, 0, 5, 120, 0, 16, 0, 0, 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0 };
            var incorrectSubType = guidRepresentation == GuidRepresentation.Standard ? BsonBinarySubType.UuidLegacy : BsonBinarySubType.UuidStandard;
            bytes[11] = (byte)incorrectSubType;
            var readerSettings = new BsonBinaryReaderSettings();
            if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2)
            {
                readerSettings.GuidRepresentation = readerGuidRepresentation;
            }
            using (var memoryStream = new MemoryStream(bytes))
                using (var reader = new BsonBinaryReader(memoryStream, readerSettings))
                {
                    var context = BsonDeserializationContext.CreateRoot(reader);

                    reader.ReadStartDocument();
                    reader.ReadName("x");
                    var exception = Record.Exception(() => subject.Deserialize <object>(context));

                    exception.Should().BeOfType <FormatException>();
                }
#pragma warning restore 618
        }
        public override IAggregateFluent <TNewResult> OfType <TNewResult>(IBsonSerializer <TNewResult> newResultSerializer)
        {
            var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(TResult));

            if (discriminatorConvention == null)
            {
                var message = string.Format("OfType requires that a discriminator convention exist for type: {0}.", BsonUtils.GetFriendlyTypeName(typeof(TResult)));
                throw new NotSupportedException(message);
            }

            var discriminatorValue = discriminatorConvention.GetDiscriminator(typeof(TResult), typeof(TNewResult));
            var ofTypeFilter       = new BsonDocument(discriminatorConvention.ElementName, discriminatorValue);

            const string operatorName = "$match";
            var          stage        = new DelegatedPipelineStageDefinition <TResult, TNewResult>(
                operatorName,
                (s, sr) =>
            {
                return(new RenderedPipelineStageDefinition <TNewResult>(
                           operatorName,
                           new BsonDocument(operatorName, ofTypeFilter),
                           newResultSerializer ?? (s as IBsonSerializer <TNewResult>) ?? sr.GetSerializer <TNewResult>()));
            });

            return(AppendStage <TNewResult>(stage));
        }
Пример #5
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 arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options);
            var itemSerializationOptions  = arraySerializationOptions.ItemSerializationOptions;

            var bsonType = bsonReader.GetCurrentBsonType();

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

            case BsonType.Array:
                var             instance = CreateInstance(actualType);
                var             itemDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
                Type            lastItemType       = null;
                IBsonSerializer lastItemSerializer = null;

                bsonReader.ReadStartArray();
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var             itemType = itemDiscriminatorConvention.GetActualType(bsonReader, typeof(object));
                    IBsonSerializer itemSerializer;
                    if (itemType == lastItemType)
                    {
                        itemSerializer = lastItemSerializer;
                    }
                    else
                    {
                        itemSerializer     = BsonSerializer.LookupSerializer(itemType);
                        lastItemType       = itemType;
                        lastItemSerializer = itemSerializer;
                    }
                    var item = itemSerializer.Deserialize(bsonReader, typeof(object), itemType, itemSerializationOptions);
                    AddItem(instance, item);
                }
                bsonReader.ReadEndArray();

                return(FinalizeResult(instance, actualType));

            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);
            }
        }
Пример #6
0
        private void SerializeDiscriminator(BsonSerializationContext context, Type nominalType, object obj)
        {
            IDiscriminatorConvention discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(_classMap.ClassType);
            BsonValue discriminator = discriminatorConvention?.GetDiscriminator(nominalType, obj.GetType());

            if (discriminator != null)
            {
                context.Writer.WriteName(discriminatorConvention.ElementName);
                BsonValueSerializer.Instance.Serialize(context, discriminator);
            }
        }
Пример #7
0
 public MongoStore(
     ILogger <MongoStore> logger,
     IClientSessionHandle session,
     IMongoCollection <Envelope> events,
     IMongoCollection <Snapshot> snapshots
     )
 {
     _logger    = logger;
     _session   = session;
     _events    = events;
     _snapshots = snapshots;
     _discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
 }
Пример #8
0
        /// <summary>
        /// Gets the discriminator convention for values.
        /// </summary>
        /// <returns>The discriminator convention for the class.</returns>
        private IDiscriminatorConvention GetValueDiscriminatorConvention()
        {
            // return a cached discriminator convention when possible
            var discriminatorConvention = _cachedValueDiscriminatorConvention;

            if (discriminatorConvention == null)
            {
                // it's possible but harmless for multiple threads to do the initial lookup at the same time
                discriminatorConvention             = BsonSerializer.LookupDiscriminatorConvention(typeof(TValue));
                _cachedValueDiscriminatorConvention = discriminatorConvention;
            }
            return(discriminatorConvention);
        }
Пример #9
0
        public static void Test_DiscriminatorConvention_01(BsonDocument document)
        {
            Trace.WriteLine("Test_DiscriminatorConvention_01");
            BsonReader bsonReader = BsonReader.Create(document);
            IDiscriminatorConvention discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(ZValue));

            Trace.WriteLine("discriminatorConvention(ZValue) : {0}", discriminatorConvention);
            Type actualType = discriminatorConvention.GetActualType(bsonReader, typeof(ZValue));

            Trace.WriteLine("actualType : {0}", actualType);
            //discriminatorConvention.GetDiscriminator()
            Trace.WriteLine();
        }
Пример #10
0
 public void SerializeBsonValue(object obj, BsonSerializingContext context)
 {
     if (obj == null)
     {
         context.BsonWriter.WriteNull();
     }
     else if (obj is IEntityHandlerProvider provider)
     {
         provider.GetHandler().SerializeBson(context);
     }
     else
     {
         var s = BsonSerializer.LookupDiscriminatorConvention(obj.GetType());
         BsonSerializer.Serialize(context.BsonWriter, obj.GetType(), obj);
     }
 }
Пример #11
0
        // public methods
        /// <summary>
        /// Deserializes a document from a BsonReader.
        /// </summary>
        /// <param name="bsonReader">The BsonReader.</param>
        /// <param name="nominalType">The nominal type of the document.</param>
        /// <param name="options">The serialization options.</param>
        /// <returns>A document.</returns>
        public override object Deserialize(
            BsonReader bsonReader,
            Type nominalType,
            IBsonSerializationOptions options)
        {
            if (!nominalType.IsInterface)
            {
                var message = string.Format("Nominal type must be an interface, not {0}.", nominalType.FullName);
                throw new ArgumentException(message, "nominalType");
            }

            var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(nominalType);
            var actualType = discriminatorConvention.GetActualType(bsonReader, nominalType);

            return(Deserialize(bsonReader, nominalType, actualType, options));
        }
Пример #12
0
        protected override UpdateDefinition <TDerivedDocument> AdjustUpdateDefinition(UpdateDefinition <TDerivedDocument> updateDefinition, bool isUpsert)
        {
            var result = base.AdjustUpdateDefinition(updateDefinition, isUpsert);

            if (isUpsert)
            {
                var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(TDerivedDocument));
                var discriminatorValue      = discriminatorConvention.GetDiscriminator(typeof(TRootDocument), typeof(TDerivedDocument));

                var builder = new UpdateDefinitionBuilder <TDerivedDocument>();
                var setOnInsertDiscriminator = builder.SetOnInsert(discriminatorConvention.ElementName, discriminatorValue);
                result = builder.Combine(result, setOnInsertDiscriminator);
            }

            return(result);
        }
Пример #13
0
        public static (AstFilterField, AstFilter) Translate(TranslationContext context, Expression sourceExpression)
        {
            if (sourceExpression is MethodCallExpression sourceMethodCallExpression)
            {
                var method    = sourceMethodCallExpression.Method;
                var arguments = sourceMethodCallExpression.Arguments;

                if (method.Is(EnumerableMethod.OfType))
                {
                    var ofTypeSourceExpression = arguments[0];
                    var(sourceField, sourceFilter) = Translate(context, ofTypeSourceExpression);

                    var nominalType                    = ArraySerializerHelper.GetItemSerializer(sourceField.Serializer).ValueType;
                    var actualType                     = method.GetGenericArguments()[0];
                    var discriminatorConvention        = BsonSerializer.LookupDiscriminatorConvention(actualType);
                    var discriminatorField             = AstFilter.Field(discriminatorConvention.ElementName, BsonValueSerializer.Instance);
                    var discriminatorValue             = discriminatorConvention.GetDiscriminator(nominalType, actualType);
                    var ofTypeFilter                   = AstFilter.Eq(discriminatorField, discriminatorValue);
                    var actualTypeSerializer           = context.KnownSerializersRegistry.GetSerializer(sourceExpression);
                    var enumerableActualTypeSerializer = IEnumerableSerializer.Create(actualTypeSerializer);
                    var actualTypeSourceField          = AstFilter.Field(sourceField.Path, enumerableActualTypeSerializer);
                    var combinedFilter                 = AstFilter.Combine(sourceFilter, ofTypeFilter);

                    return(actualTypeSourceField, combinedFilter);
                }

                if (method.Is(EnumerableMethod.Where))
                {
                    var whereSourceExpression = arguments[0];
                    var(sourceField, sourceFilter) = Translate(context, whereSourceExpression);

                    var predicateLambda     = (LambdaExpression)arguments[1];
                    var parameterExpression = predicateLambda.Parameters.Single();
                    var itemSerializer      = ArraySerializerHelper.GetItemSerializer(sourceField.Serializer);
                    var parameterSymbol     = context.CreateSymbol(parameterExpression, "@<elem>", itemSerializer); // @<elem> represents the implied element
                    var predicateContext    = context.WithSingleSymbol(parameterSymbol);                            // @<elem> is the only symbol visible inside an $elemMatch
                    var whereFilter         = ExpressionToFilterTranslator.Translate(predicateContext, predicateLambda.Body, exprOk: false);
                    var combinedFilter      = AstFilter.Combine(sourceFilter, whereFilter);

                    return(sourceField, combinedFilter);
                }
            }

            var field = ExpressionToFilterFieldTranslator.Translate(context, sourceExpression);

            return(field, null);
        }
Пример #14
0
        public object Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var      bsonReader = context.Reader;
            BsonType bsonType   = bsonReader.CurrentBsonType;

            object result;

            if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                result = null;
            }
            else
            {
                if (bsonType == BsonType.Document)
                {
                    var dictionary = new DynamicDictionary();

                    bsonReader.ReadStartDocument();

                    IDiscriminatorConvention valueDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));

                    while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                    {
                        string          key             = bsonReader.ReadName();
                        Type            valueType       = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(object));
                        IBsonSerializer valueSerializer = BsonSerializer.LookupSerializer(valueType);
                        object          value           = valueSerializer.Deserialize(context);

                        if (key != "_t")
                        {
                            dictionary.Add(key.Replace('\x03', '.'), value);
                        }
                    }
                    bsonReader.ReadEndDocument();
                    result = dictionary;
                }
                else
                {
                    string message = string.Format("Can't deserialize a {0} from BsonType {1}.", context.Reader.CurrentBsonType, bsonType);
                    throw new BsonException(message);
                }
            }

            return(result);
        }
        // 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)
        {
            VerifyTypes(nominalType, actualType, typeof(T[]));
            var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options);
            var itemSerializationOptions  = arraySerializationOptions.ItemSerializationOptions;

            var bsonType = bsonReader.GetCurrentBsonType();

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

            case BsonType.Array:
                bsonReader.ReadStartArray();
                var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(T));
                var list = new List <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, itemSerializationOptions);
                    list.Add(element);
                }
                bsonReader.ReadEndArray();
                return(list.ToArray());

            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}.", actualType.FullName, bsonType);
                throw new FileFormatException(message);
            }
        }
Пример #16
0
        public static AstFilter Translate(TranslationContext context, TypeBinaryExpression expression)
        {
            if (expression.NodeType == ExpressionType.TypeIs)
            {
                var fieldExpression = expression.Expression;
                var field           = ExpressionToFilterFieldTranslator.Translate(context, fieldExpression);

                var nominalType             = fieldExpression.Type;
                var actualType              = expression.TypeOperand;
                var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(actualType);
                var discriminatorField      = field.SubField(discriminatorConvention.ElementName, BsonValueSerializer.Instance);
                var discriminator           = discriminatorConvention.GetDiscriminator(nominalType, actualType);

                return(AstFilter.Eq(discriminatorField, discriminator));
            }

            throw new ExpressionNotSupportedException(expression);
        }
Пример #17
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="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 {0}.", nominalType.FullName);
                throw new InvalidOperationException(message);
            }

            var bsonType = bsonReader.GetCurrentBsonType();

            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 = BsonSerializer.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));
        }
        public void Serialize_guid_should_have_expected_result_when_guid_representation_is_unspecified_and_mode_is_v2(
            [Values(GuidRepresentation.CSharpLegacy, GuidRepresentation.JavaLegacy, GuidRepresentation.PythonLegacy, GuidRepresentation.Standard, GuidRepresentation.Unspecified)]
            GuidRepresentation defaultGuidRepresentation,
            [Values(GuidRepresentation.CSharpLegacy, GuidRepresentation.JavaLegacy, GuidRepresentation.PythonLegacy, GuidRepresentation.Standard, GuidRepresentation.Unspecified)]
            GuidRepresentation writerGuidRepresentation)
        {
#pragma warning disable 618
            var expectedGuidRepresentation = writerGuidRepresentation != GuidRepresentation.Unspecified ? writerGuidRepresentation : defaultGuidRepresentation;
            if (expectedGuidRepresentation == GuidRepresentation.Unspecified)
            {
                throw new SkipException("Test skipped because expectedGuidRepresentation is Unspecified.");
            }
            BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V2;
            BsonDefaults.GuidRepresentation     = defaultGuidRepresentation;
            var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
            var subject        = new ObjectSerializer(discriminatorConvention, GuidRepresentation.Unspecified);
            var writerSettings = new BsonBinaryWriterSettings();
            if (writerGuidRepresentation != GuidRepresentation.Unspecified)
            {
                writerSettings.GuidRepresentation = writerGuidRepresentation;
            }
            using (var memoryStream = new MemoryStream())
                using (var writer = new BsonBinaryWriter(memoryStream, writerSettings))
                {
                    var context = BsonSerializationContext.CreateRoot(writer);
                    var guid    = Guid.Parse("01020304-0506-0708-090a-0b0c0d0e0f10");

                    writer.WriteStartDocument();
                    writer.WriteName("x");
                    subject.Serialize(context, guid);
                    writer.WriteEndDocument();

                    var bytes             = memoryStream.ToArray();
                    var expectedBytes     = new byte[] { 29, 0, 0, 0, 5, 120, 0, 16, 0, 0, 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0 };
                    var expectedSubType   = GuidConverter.GetSubType(expectedGuidRepresentation);
                    var expectedGuidBytes = GuidConverter.ToBytes(guid, expectedGuidRepresentation);
                    expectedBytes[11] = (byte)expectedSubType;
                    Array.Copy(expectedGuidBytes, 0, expectedBytes, 12, 16);
                    bytes.Should().Equal(expectedBytes);
                }
#pragma warning restore 618
        }
        public void Deserialize_binary_data_should_throw_when_guid_representation_is_unspecified_and_mode_is_v3()
        {
#pragma warning disable 618
            BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;
            var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
            var subject = new ObjectSerializer(discriminatorConvention, GuidRepresentation.Unspecified);
            var bytes   = new byte[] { 29, 0, 0, 0, 5, 120, 0, 16, 0, 0, 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0 };
            using (var memoryStream = new MemoryStream(bytes))
                using (var reader = new BsonBinaryReader(memoryStream))
                {
                    var context = BsonDeserializationContext.CreateRoot(reader);

                    reader.ReadStartDocument();
                    reader.ReadName("x");
                    var exception = Record.Exception(() => subject.Deserialize <object>(context));

                    exception.Should().BeOfType <BsonSerializationException>();
                }
#pragma warning restore 618
        }
        public void Serialize_guid_should_throw_when_guid_representation_is_unspecified_and_mode_is_v3()
        {
#pragma warning disable 618
            BsonDefaults.GuidRepresentationMode = GuidRepresentationMode.V3;
            var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
            var subject = new ObjectSerializer(discriminatorConvention, GuidRepresentation.Unspecified);
            using (var memoryStream = new MemoryStream())
                using (var writer = new BsonBinaryWriter(memoryStream))
                {
                    var context = BsonSerializationContext.CreateRoot(writer);
                    var guid    = Guid.Parse("01020304-0506-0708-090a-0b0c0d0e0f10");

                    writer.WriteStartDocument();
                    writer.WriteName("x");
                    var exception = Record.Exception(() => subject.Serialize(context, guid));

                    exception.Should().BeOfType <BsonSerializationException>();
                }
#pragma warning restore 618
        }
Пример #21
0
        // public static methods
        public static AstPipeline Translate(TranslationContext context, MethodCallExpression expression)
        {
            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.Is(QueryableMethod.OfType))
            {
                var sourceExpression = arguments[0];
                var pipeline         = ExpressionToPipelineTranslator.Translate(context, sourceExpression);

                var sourceType                   = sourceExpression.Type;
                var nominalType                  = sourceType.GetGenericArguments()[0];
                var actualType                   = method.GetGenericArguments()[0];
                var discriminatorConvention      = BsonSerializer.LookupDiscriminatorConvention(nominalType);
                var discriminatorElementName     = discriminatorConvention.ElementName;
                var wrappedValueOutputSerializer = pipeline.OutputSerializer as IWrappedValueSerializer;
                if (wrappedValueOutputSerializer != null)
                {
                    discriminatorElementName = wrappedValueOutputSerializer.FieldName + "." + discriminatorElementName;
                }
                var discriminatorField = AstFilter.Field(discriminatorElementName, BsonValueSerializer.Instance);
                var discriminatorValue = discriminatorConvention.GetDiscriminator(nominalType, actualType);
                var filter             = AstFilter.Eq(discriminatorField, discriminatorValue); // note: OfType only works with hierarchical discriminators
                var actualSerializer   = context.KnownSerializersRegistry.GetSerializer(expression);
                if (wrappedValueOutputSerializer != null)
                {
                    actualSerializer = WrappedValueSerializer.Create(wrappedValueOutputSerializer.FieldName, actualSerializer);
                }

                pipeline = pipeline.AddStages(
                    actualSerializer,
                    AstStage.Match(filter));

                return(pipeline);
            }

            throw new ExpressionNotSupportedException(expression);
        }
Пример #22
0
        // public methods
        /// <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 = BsonSerializer.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));
        }
Пример #23
0
        /// <summary>
        /// Gets the actual type.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns>The actual type.</returns>
        protected virtual Type GetActualType(BsonDeserializationContext context)
        {
            var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(TValue));

            return(discriminatorConvention.GetActualType(context.Reader, typeof(TValue)));
        }
Пример #24
0
 // constructors
 /// <summary>
 /// Initializes a new instance of the <see cref="DiscriminatedInterfaceSerializer{TInterface}" /> class.
 /// </summary>
 public DiscriminatedInterfaceSerializer()
     : this(BsonSerializer.LookupDiscriminatorConvention(typeof(TInterface)))
 {
 }
Пример #25
0
        private void TranslateOfType(MethodCallExpression methodCallExpression)
        {
            var method = methodCallExpression.Method;

            if (method.DeclaringType != typeof(Queryable))
            {
                var message = string.Format("OfType method of class {0} is not supported.", BsonUtils.GetFriendlyTypeName(method.DeclaringType));
                throw new NotSupportedException(message);
            }
            if (!method.IsStatic)
            {
                throw new NotSupportedException("Expected OfType to be a static method.");
            }
            if (!method.IsGenericMethod)
            {
                throw new NotSupportedException("Expected OfType to be a generic method.");
            }
            var actualType = method.GetGenericArguments()[0];

            var args = methodCallExpression.Arguments.ToArray();

            if (args.Length != 1)
            {
                throw new NotSupportedException("Expected OfType method to have a single argument.");
            }
            var sourceExpression = args[0];

            if (!sourceExpression.Type.IsGenericType)
            {
                throw new NotSupportedException("Expected source argument to OfType to be a generic type.");
            }
            var nominalType = sourceExpression.Type.GetGenericArguments()[0];

            if (_projection != null)
            {
                throw new NotSupportedException("OfType after a projection is not supported.");
            }

            var discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(nominalType);
            var discriminator           = discriminatorConvention.GetDiscriminator(nominalType, actualType);

            if (discriminator == null)
            {
                return; // nothing to do
            }

            if (discriminator.IsBsonArray)
            {
                discriminator = discriminator.AsBsonArray[discriminator.AsBsonArray.Count - 1];
            }
            var query = Query.EQ(discriminatorConvention.ElementName, discriminator);

            var injectMethodInfo = typeof(LinqToMongo).GetMethod("Inject");
            var body             = Expression.Call(injectMethodInfo, Expression.Constant(query));
            var parameter        = Expression.Parameter(nominalType, "x");
            var predicate        = Expression.Lambda(body, parameter);

            CombinePredicateWithWhereClause(methodCallExpression, predicate);

            _ofType = actualType;
        }
Пример #26
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 dictionarySerializationOptions   = EnsureSerializationOptions(options);
            var keyValuePairSerializationOptions = dictionarySerializationOptions.KeyValuePairSerializationOptions;

            var bsonType = bsonReader.GetCurrentBsonType();

            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(actualType);
                var valueDiscriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));

                bsonReader.ReadStartDocument();
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var key             = bsonReader.ReadName();
                    var valueType       = valueDiscriminatorConvention.GetActualType(bsonReader, typeof(object));
                    var valueSerializer = BsonSerializer.LookupSerializer(valueType);
                    var value           = valueSerializer.Deserialize(bsonReader, typeof(object), valueType, keyValuePairSerializationOptions.ValueSerializationOptions);
                    dictionary.Add(key, value);
                }
                bsonReader.ReadEndDocument();

                return(dictionary);
            }
            else if (bsonType == BsonType.Array)
            {
                var dictionary = CreateInstance(actualType);

                bsonReader.ReadStartArray();
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    var keyValuePair = (KeyValuePair <object, object>)_keyValuePairSerializer.Deserialize(
                        bsonReader,
                        typeof(KeyValuePair <object, object>),
                        keyValuePairSerializationOptions);
                    dictionary.Add(keyValuePair.Key, keyValuePair.Value);
                }
                bsonReader.ReadEndArray();

                return(dictionary);
            }
            else
            {
                var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
                throw new Exception(message);
            }
        }
Пример #27
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)
        {
            VerifyTypes(nominalType, actualType, typeof(T[, ]));
            var arraySerializationOptions = EnsureSerializationOptions <ArraySerializationOptions>(options);
            var itemSerializationOptions  = arraySerializationOptions.ItemSerializationOptions;

            var    bsonType = bsonReader.GetCurrentBsonType();
            string message;

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

            case BsonType.Array:
                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;

                bsonReader.ReadStartArray();
                var outerList = new List <List <T> >();
                while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                {
                    bsonReader.ReadStartArray();
                    var innerList = new List <T>();
                    while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
                    {
                        if (!itemNominalTypeIsValueType)
                        {
                            itemActualType = itemDiscriminatorConvention.GetActualType(bsonReader, itemNominalType);
                            if (itemActualType == itemNominalType)
                            {
                                itemActualTypeSerializer = itemNominalTypeSerializer;
                            }
                            else if (itemActualType == lastItemType)
                            {
                                itemActualTypeSerializer = lastItemSerializer;
                            }
                            else
                            {
                                itemActualTypeSerializer = BsonSerializer.LookupSerializer(itemActualType);
                                lastItemType             = itemActualType;
                                lastItemSerializer       = itemActualTypeSerializer;
                            }
                        }
                        var item = (T)itemActualTypeSerializer.Deserialize(bsonReader, itemNominalType, itemActualType, itemSerializationOptions);
                        innerList.Add(item);
                    }
                    bsonReader.ReadEndArray();
                    outerList.Add(innerList);
                }
                bsonReader.ReadEndArray();

                var length1 = outerList.Count;
                var length2 = (length1 == 0) ? 0 : outerList[0].Count;
                var array   = new T[length1, length2];
                for (int i = 0; i < length1; i++)
                {
                    var innerList = outerList[i];
                    if (innerList.Count != length2)
                    {
                        message = string.Format("Inner list {0} is of length {1} but should be of length {2}.", i, innerList.Count, length2);
                        throw new FileFormatException(message);
                    }
                    for (int j = 0; j < length2; j++)
                    {
                        array[i, j] = innerList[j];
                    }
                }

                return(array);

            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:
                message = string.Format("Can't deserialize a {0} from BsonType {1}.", actualType.FullName, bsonType);
                throw new FileFormatException(message);
            }
        }
Пример #28
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();
            }
        }
 // constructors
 /// <summary>
 /// Initializes a new instance of the <see cref="ObjectSerializer"/> class.
 /// </summary>
 public ObjectSerializer()
     : this(BsonSerializer.LookupDiscriminatorConvention(typeof(object)))
 {
 }
Пример #30
0
        /***************************************************/
        /**** Constructors                              ****/
        /***************************************************/

        public BH_ObjectSerializer()
        {
            _discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(object));
        }