private static string WriteInstanceAnnotation(ODataInstanceAnnotation instanceAnnotation, IEdmModel model)
        {
            var stringWriter = new StringWriter();
            var outputContext = new ODataJsonLightOutputContext(
                ODataFormat.Json,
                stringWriter,
                new ODataMessageWriterSettings { Version = ODataVersion.V4, ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("*") },
                model);

            var valueSerializer = new ODataJsonLightValueSerializer(outputContext);

            // The JSON Writer will complain if there is no active scope, so start an object scope.
            valueSerializer.JsonWriter.StartObjectScope();
            var instanceAnnotationWriter = new JsonLightInstanceAnnotationWriter(valueSerializer, new JsonMinimalMetadataTypeNameOracle());

            // The method under test.
            instanceAnnotationWriter.WriteInstanceAnnotation(instanceAnnotation);

            valueSerializer.JsonWriter.EndObjectScope();
            return stringWriter.ToString();
        }
        public void WriteInstanceAnnotationShouldPassComplexTypeFromModelToUnderlyingWriter()
        {
            // Add a value term of a complex type to the model.
            var complexTypeReference = new EdmComplexTypeReference(new EdmComplexType("My.Namespace", "ComplexType"), false /*isNullable*/);
            this.referencedModel.AddElement(new EdmTerm("My.Namespace", "StructuredTerm", complexTypeReference));
            var instanceAnnotation = new ODataInstanceAnnotation("My.Namespace.StructuredTerm", new ODataComplexValue { TypeName = "ComplexType" });

            bool calledWriteComplex = false;

            this.valueWriter.WriteComplexVerifier = (complexValue, typeReference, isTopLevel, isOpenProperty, dupChecker) =>
            {
                typeReference.Should().NotBeNull();
                typeReference.IsComplex().Should().BeTrue();
                typeReference.AsComplex().FullName().Should().Be("My.Namespace.ComplexType");
                calledWriteComplex = true;
            };

            this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(instanceAnnotation);
            calledWriteComplex.Should().BeTrue();
        }
        public void WriteInstanceAnnotationShouldPassCollectionTypeFromModelToUnderlyingWriter()
        {
            // Add a value term of type Collection(Edm.String) to the model.
            this.referencedModel.AddElement(new EdmTerm(
                "My.Namespace",
                "CollectionTerm",
                new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetString(false)))));

            var instanceAnnotation = new ODataInstanceAnnotation("My.Namespace.CollectionTerm", new ODataCollectionValue() { TypeName = "Collection(Edm.String)" });

            bool calledWriteCollection = false;

            this.valueWriter.WriteCollectionVerifier = (collectionValue, typeReference, isTopLevel, isOpenProperty, dupChecker) =>
            {
                typeReference.Should().NotBeNull();
                typeReference.IsCollection().Should().BeTrue();
                typeReference.AsCollection().ElementType().IsString().Should().BeTrue();
                calledWriteCollection = true;
            };

            var result = WriteInstanceAnnotation(instanceAnnotation, this.referencedModel);
            result.Should().Contain("{\"@My.Namespace.CollectionTerm\":[]}");
            result.Should().NotContain("odata.type");

            this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(instanceAnnotation);
            calledWriteCollection.Should().BeTrue();
        }
        public void WriteTopLevelErrorWithDateTimeInstanceAnnotation()
        {
            var result = SetupSerializerAndRunTest(null, serializer =>
            {
                ODataError error = new ODataError();
                var instanceAnnotations = new Collection<ODataInstanceAnnotation>();
                var primitiveValue = new ODataPrimitiveValue(new DateTimeOffset(2000, 1, 1, 12, 30, 0, new TimeSpan()));
                ODataInstanceAnnotation annotation = new ODataInstanceAnnotation("sample.primitive", primitiveValue);
                instanceAnnotations.Add(annotation);
                error.InstanceAnnotations = instanceAnnotations;

                serializer.WriteTopLevelError(error, false);
            });

            result.Should().Contain("\"[email protected]\":\"#DateTimeOffset\",\"@sample.primitive\":\"2000-01-01T12:30:00Z\"");
        }
        public void WriteInstanceAnnotationShouldWriteValueTypeIfMoreDerivedThanMetadataType()
        {
            // Add a value term of type Geography to the model.
            this.referencedModel.AddElement(new EdmTerm("My.Namespace", "GeographyTerm", EdmPrimitiveTypeKind.Geography));
            var instanceAnnotation = new ODataInstanceAnnotation("My.Namespace.GeographyTerm", new ODataPrimitiveValue(GeographyPoint.Create(0.0, 0.0)));

            bool writingTypeName = false;
            bool wroteTypeName = false;
            this.jsonWriter.WriteNameVerifier = s =>
            {
                writingTypeName = s.EndsWith("odata.type");
            };

            this.jsonWriter.WriteValueVerifier = s =>
            {
                if (writingTypeName)
                {
                    s.Should().Be("#GeographyPoint");
                    wroteTypeName = true;
                }
            };

            this.valueWriter.WritePrimitiveVerifier = (o, reference) => { };

            this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(instanceAnnotation);

            wroteTypeName.Should().BeTrue();
        }
        /// <summary>
        /// Writes an ODataError with the given custom instance annotation to the test stream.
        /// </summary>
        private void WriteError(params KeyValuePair<string, ODataValue>[] annotations)
        {
            var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true };
            writerSettings.SetContentType(ODataFormat.Json);
            writerSettings.SetServiceDocumentUri(new Uri("http://example.com/"));

            IODataResponseMessage messageToWrite = new InMemoryMessage { StatusCode = 400, Stream = this.stream };

            var error = new ODataError();
            var instanceAnnotations = new Collection<ODataInstanceAnnotation>();
            error.SetInstanceAnnotations(instanceAnnotations);

            foreach (var pair in annotations)
            {
                ODataInstanceAnnotation annotation = new ODataInstanceAnnotation(pair.Key, pair.Value);
                instanceAnnotations.Add(annotation);
            }

            using (var writer = new ODataMessageWriter(messageToWrite, writerSettings, this.model))
            {
                writer.WriteError(error, false);
            }
        }
 public void TheNamePropertyShouldReturnTheAnnotationName()
 {
     const string name = "instance.annotation";
     var annotation = new ODataInstanceAnnotation(name, new ODataPrimitiveValue("value"));
     annotation.Name.Should().Be(name);
 }
        public void WriteTopLevelErrorWithCollectionOfComplexInstanceAnnotationWithNoTypeNameShouldThrow()
        {
            SetupSerializerAndRunTest(null, serializer =>
            {
                ODataError error = new ODataError();
                var instanceAnnotations = new Collection<ODataInstanceAnnotation>();
                var collection = new ODataCollectionValue
                {
                    Items = new[] { new ODataComplexValue(), new ODataComplexValue { TypeName = "ns.ErrorDetails" } }
                };
                ODataInstanceAnnotation annotation = new ODataInstanceAnnotation("sample.collection", collection);
                instanceAnnotations.Add(annotation);
                error.InstanceAnnotations = instanceAnnotations;

                Action writeError = () => serializer.WriteTopLevelError(error, false);
                writeError.ShouldThrow<ODataException>().WithMessage(Strings.WriterValidationUtils_MissingTypeNameWithMetadata);
            });
        }
        public void WriteTopLevelErrorWithStringInstanceAnnotation()
        {
            var result = SetupSerializerAndRunTest(null, serializer =>
            {
                ODataError error = new ODataError();
                var instanceAnnotations = new Collection<ODataInstanceAnnotation>();
                ODataInstanceAnnotation annotation = new ODataInstanceAnnotation("sample.primitive", new ODataPrimitiveValue("stringValue"));
                instanceAnnotations.Add(annotation);
                error.InstanceAnnotations = instanceAnnotations;

                serializer.WriteTopLevelError(error, false);
            });

            result.Should().Contain("\"@sample.primitive\":\"stringValue\"");
        }
        public void WriteTopLevelErrorWithComplexInstanceAnnotation()
        {
            var result = SetupSerializerAndRunTest(null, serializer =>
            {
                ODataError error = new ODataError();
                var instanceAnnotations = new Collection<ODataInstanceAnnotation>();
                var complexValue = new ODataComplexValue();
                complexValue.TypeName = "ns.ErrorDetails";
                ODataInstanceAnnotation annotation = new ODataInstanceAnnotation("sample.complex", complexValue);
                instanceAnnotations.Add(annotation);
                error.InstanceAnnotations = instanceAnnotations;

                serializer.WriteTopLevelError(error, false);
            });

            result.Should().Contain("\"@sample.complex\":{\"@odata.type\":\"#ns.ErrorDetails\"}");
        }
        public void WriteTopLevelErrorWithCollectionOfComplexInstanceAnnotation()
        {
            var result = SetupSerializerAndRunTest(null, serializer =>
            {
                ODataError error = new ODataError();
                var instanceAnnotations = new Collection<ODataInstanceAnnotation>();
                var collection = new ODataCollectionValue
                {
                    TypeName = "Collection(ns.ErrorDetails)",
                    Items = new[] { new ODataComplexValue(), new ODataComplexValue { TypeName = "ns.ErrorDetails" } }
                };
                ODataInstanceAnnotation annotation = new ODataInstanceAnnotation("sample.collection", collection);
                instanceAnnotations.Add(annotation);
                error.InstanceAnnotations = instanceAnnotations;

                serializer.WriteTopLevelError(error, false);
            });

            result.Should().Contain("\"[email protected]\":\"#Collection(ns.ErrorDetails)\",\"@sample.collection\":[{},{}]");
        }
        public void WriteTopLevelErrorWithStringInstanceAnnotationWithTypeNameAttribute()
        {
            var result = SetupSerializerAndRunTest(null, serializer =>
            {
                ODataError error = new ODataError();
                var instanceAnnotations = new Collection<ODataInstanceAnnotation>();
                var primitiveValue = new ODataPrimitiveValue("stringValue");
                primitiveValue.SetAnnotation(new SerializationTypeNameAnnotation() { TypeName = "Custom.Type" });
                ODataInstanceAnnotation annotation = new ODataInstanceAnnotation("sample.primitive", primitiveValue);
                instanceAnnotations.Add(annotation);
                error.InstanceAnnotations = instanceAnnotations;

                serializer.WriteTopLevelError(error, false);
            });

            result.Should().Contain("\"[email protected]\":\"#Custom.Type\",\"@sample.primitive\":\"stringValue\"");
        }
        public void WriteTopLevelErrorWithTimeOfDayInstanceAnnotation()
        {
            var result = SetupSerializerAndRunTest(null, serializer =>
            {
                ODataError error = new ODataError();
                var instanceAnnotations = new Collection<ODataInstanceAnnotation>();
                var primitiveValue = new ODataPrimitiveValue(new TimeOfDay(12, 30, 5, 90));
                ODataInstanceAnnotation annotation = new ODataInstanceAnnotation("sample.primitive", primitiveValue);
                instanceAnnotations.Add(annotation);
                error.InstanceAnnotations = instanceAnnotations;

                serializer.WriteTopLevelError(error, false);
            });

            result.Should().Contain("\"[email protected]\":\"#TimeOfDay\",\"@sample.primitive\":\"12:30:05.0900000\"");
        }
        public void WriteTopLevelErrorWithDateInstanceAnnotation()
        {
            var result = SetupSerializerAndRunTest(null, serializer =>
            {
                ODataError error = new ODataError();
                var instanceAnnotations = new Collection<ODataInstanceAnnotation>();
                var primitiveValue = new ODataPrimitiveValue(new Date(2014, 8, 8));
                ODataInstanceAnnotation annotation = new ODataInstanceAnnotation("sample.primitive", primitiveValue);
                instanceAnnotations.Add(annotation);
                error.InstanceAnnotations = instanceAnnotations;

                serializer.WriteTopLevelError(error, false);
            });

            result.Should().Contain("\"[email protected]\":\"#Date\",\"@sample.primitive\":\"2014-08-08\"");
        }
        public void WriteInstanceAnnotationShouldSkipAnnotationsThatDoesNotPassTheAnnotationFilter()
        {
            var annotation = new ODataInstanceAnnotation("ns1.name", new ODataPrimitiveValue(123));
            var verifierCalls = 0;

            this.jsonWriter.WriteNameVerifier = (name) => verifierCalls++;
            this.valueWriter.WritePrimitiveVerifier = (value, reference) => verifierCalls++;
            this.valueWriter.Settings = new ODataMessageWriterSettings { Version = ODataVersion.V4, ShouldIncludeAnnotation = name => name != "ns1.name" };

            this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(annotation);
            verifierCalls.Should().Be(0);
        }
Example #16
0
        /// <summary>
        /// Writes an instance annotation.
        /// </summary>
        /// <param name="instanceAnnotation">The instance annotation to write.</param>
        /// <param name="ignoreFilter">Whether to ingore the filter in settings.</param>
        /// <param name="propertyName">The name of the property this instance annotation applies to</param>
        internal void WriteInstanceAnnotation(ODataInstanceAnnotation instanceAnnotation, bool ignoreFilter = false, string propertyName = null)
        {
            string     name  = instanceAnnotation.Name;
            ODataValue value = instanceAnnotation.Value;

            Debug.Assert(!string.IsNullOrEmpty(name), "name should not be null or empty");
            Debug.Assert(!ODataAnnotationNames.IsODataAnnotationName(name), "A reserved name cannot be used as instance annotation key");
            Debug.Assert(value != null, "value should not be null because we use ODataNullValue for null instead");
            Debug.Assert(!(value is ODataStreamReferenceValue), "!(value is ODataStreamReferenceValue) -- ODataInstanceAnnotation and InstanceAnnotationCollection will throw if the value is a stream value.");
            Debug.Assert(this.valueSerializer.Model != null, "this.valueSerializer.Model != null");

            if (!ignoreFilter && this.valueSerializer.Settings.ShouldSkipAnnotation(name))
            {
                return;
            }

            IEdmTypeReference expectedType = MetadataUtils.LookupTypeOfValueTerm(name, this.valueSerializer.Model);

            if (value is ODataNullValue)
            {
                if (expectedType != null && !expectedType.IsNullable)
                {
                    throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueSerializer_NullValueNotAllowedForInstanceAnnotation(instanceAnnotation.Name, expectedType.ODataFullName()));
                }

                this.WriteInstanceAnnotationName(propertyName, name);
                this.valueSerializer.WriteNullValue();
                return;
            }

            // If we didn't find an expected type from looking up the term in the model, treat this value the same way we would for open property values.
            // That is, write the type name (unless its a primitive value with a JSON-native type).  If we did find an expected type, treat the annotation value like a
            // declared property with an expected type. This will still write out the type if the value type is more derived than the declared type, for example.
            bool treatLikeOpenProperty = expectedType == null;

            ODataComplexValue complexValue = value as ODataComplexValue;

            if (complexValue != null)
            {
                this.WriteInstanceAnnotationName(propertyName, name);
                this.valueSerializer.WriteComplexValue(complexValue, expectedType, false /*isTopLevel*/, treatLikeOpenProperty, this.valueSerializer.CreateDuplicatePropertyNamesChecker());
                return;
            }

            IEdmTypeReference    typeFromValue   = TypeNameOracle.ResolveAndValidateTypeNameForValue(this.valueSerializer.Model, expectedType, value, treatLikeOpenProperty);
            ODataCollectionValue collectionValue = value as ODataCollectionValue;

            if (collectionValue != null)
            {
                string collectionTypeNameToWrite = this.typeNameOracle.GetValueTypeNameForWriting(collectionValue, expectedType, typeFromValue, treatLikeOpenProperty);
                if (collectionTypeNameToWrite != null)
                {
                    ODataJsonLightWriterUtils.WriteODataTypePropertyAnnotation(this.JsonWriter, name, collectionTypeNameToWrite);
                }

                this.WriteInstanceAnnotationName(propertyName, name);
                this.valueSerializer.WriteCollectionValue(collectionValue, expectedType, false /*isTopLevelProperty*/, false /*isInUri*/, treatLikeOpenProperty);
                return;
            }

            ODataPrimitiveValue primitiveValue = value as ODataPrimitiveValue;

            Debug.Assert(primitiveValue != null, "Did we add a new subclass of ODataValue?");

            string primitiveTypeNameToWrite = this.typeNameOracle.GetValueTypeNameForWriting(primitiveValue, expectedType, typeFromValue, treatLikeOpenProperty);

            if (primitiveTypeNameToWrite != null)
            {
                ODataJsonLightWriterUtils.WriteODataTypePropertyAnnotation(this.JsonWriter, name, primitiveTypeNameToWrite);
            }

            this.WriteInstanceAnnotationName(propertyName, name);
            this.valueSerializer.WritePrimitiveValue(primitiveValue.Value, expectedType);
        }
        /// <summary>
        /// Writes an instance annotation.
        /// </summary>
        /// <param name="instanceAnnotation">The instance annotation to write.</param>
        /// <param name="ignoreFilter">Whether to ignore the filter in settings.</param>
        /// <param name="propertyName">The name of the property this instance annotation applies to</param>
        internal void WriteInstanceAnnotation(ODataInstanceAnnotation instanceAnnotation, bool ignoreFilter = false, string propertyName = null)
        {
            string name = instanceAnnotation.Name;
            ODataValue value = instanceAnnotation.Value;
            Debug.Assert(!string.IsNullOrEmpty(name), "name should not be null or empty");
            Debug.Assert(!ODataAnnotationNames.IsODataAnnotationName(name), "A reserved name cannot be used as instance annotation key");
            Debug.Assert(value != null, "value should not be null because we use ODataNullValue for null instead");
            Debug.Assert(!(value is ODataStreamReferenceValue), "!(value is ODataStreamReferenceValue) -- ODataInstanceAnnotation and InstanceAnnotationCollection will throw if the value is a stream value.");
            Debug.Assert(this.valueSerializer.Model != null, "this.valueSerializer.Model != null");

            if (!ignoreFilter && this.valueSerializer.Settings.ShouldSkipAnnotation(name))
            {
                return;
            }

            IEdmTypeReference expectedType = MetadataUtils.LookupTypeOfValueTerm(name, this.valueSerializer.Model);

            if (value is ODataNullValue)
            {
                if (expectedType != null && !expectedType.IsNullable)
                {
                    throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueSerializer_NullValueNotAllowedForInstanceAnnotation(instanceAnnotation.Name, expectedType.ODataFullName()));
                }

                this.WriteInstanceAnnotationName(propertyName, name);
                this.valueSerializer.WriteNullValue();
                return;
            }

            // If we didn't find an expected type from looking up the term in the model, treat this value the same way we would for open property values. 
            // That is, write the type name (unless its a primitive value with a JSON-native type).  If we did find an expected type, treat the annotation value like a 
            // declared property with an expected type. This will still write out the type if the value type is more derived than the declared type, for example.
            bool treatLikeOpenProperty = expectedType == null;

            ODataComplexValue complexValue = value as ODataComplexValue;
            if (complexValue != null)
            {
                this.WriteInstanceAnnotationName(propertyName, name);
                this.valueSerializer.WriteComplexValue(complexValue, expectedType, false /*isTopLevel*/, treatLikeOpenProperty, this.valueSerializer.CreateDuplicatePropertyNamesChecker());
                return;
            }

            IEdmTypeReference typeFromValue = TypeNameOracle.ResolveAndValidateTypeNameForValue(this.valueSerializer.Model, expectedType, value, treatLikeOpenProperty);
            ODataCollectionValue collectionValue = value as ODataCollectionValue;
            if (collectionValue != null)
            {
                string collectionTypeNameToWrite = this.typeNameOracle.GetValueTypeNameForWriting(collectionValue, expectedType, typeFromValue, treatLikeOpenProperty);
                if (collectionTypeNameToWrite != null)
                {
                    ODataJsonLightWriterUtils.WriteODataTypePropertyAnnotation(this.JsonWriter, name, collectionTypeNameToWrite);
                }

                this.WriteInstanceAnnotationName(propertyName, name);
                this.valueSerializer.WriteCollectionValue(collectionValue, expectedType, false /*isTopLevelProperty*/, false /*isInUri*/, treatLikeOpenProperty);
                return;
            }

            ODataPrimitiveValue primitiveValue = value as ODataPrimitiveValue;
            Debug.Assert(primitiveValue != null, "Did we add a new subclass of ODataValue?");

            string primitiveTypeNameToWrite = this.typeNameOracle.GetValueTypeNameForWriting(primitiveValue, expectedType, typeFromValue, treatLikeOpenProperty);
            if (primitiveTypeNameToWrite != null)
            {
                ODataJsonLightWriterUtils.WriteODataTypePropertyAnnotation(this.JsonWriter, name, primitiveTypeNameToWrite);
            }

            this.WriteInstanceAnnotationName(propertyName, name);
            this.valueSerializer.WritePrimitiveValue(primitiveValue.Value, expectedType);
        }
Example #18
0
 public void GetInstanceAnnotationsForWritingShouldReturnInstanceAnnotationsFromODataErrorWithInstanceAnnotations()
 {
     ODataInstanceAnnotation instanceAnnotation = new ODataInstanceAnnotation("namespace.name", new ODataPrimitiveValue("value"));
     this.odataError.InstanceAnnotations.Add(instanceAnnotation);
     this.odataError.InstanceAnnotations.Should().Contain(instanceAnnotation).And.HaveCount(1);
 }
        /// <summary>
        /// Convert an instance annotation to clr object.
        /// </summary>
        /// <param name="instanceAnnotation">Instance annotation to be converted</param>
        /// <param name="clrInstanceAnnotation">The clr object</param>
        /// <returns>A dictionary of clr-typed instance annotation</returns>
        private bool TryConvertToClrInstanceAnnotation(ODataInstanceAnnotation instanceAnnotation, out object clrInstanceAnnotation)
        {
            clrInstanceAnnotation = null;

            var primitiveValue = instanceAnnotation.Value as ODataPrimitiveValue;
            if (primitiveValue != null)
            {
                clrInstanceAnnotation = primitiveValue.Value;
                return true;
            }

            var enumValue = instanceAnnotation.Value as ODataEnumValue;
            if (enumValue != null)
            {
                var type = this.MaterializerContext.Context.ResolveTypeFromName(enumValue.TypeName);
                if (type != null)
                {
                    clrInstanceAnnotation = EnumValueMaterializationPolicy.MaterializeODataEnumValue(type, enumValue);
                    return true;
                }

                return false;
            }

            var complexValue = instanceAnnotation.Value as ODataComplexValue;
            if (complexValue != null)
            {
                var type = this.MaterializerContext.Context.ResolveTypeFromName(complexValue.TypeName);
                if (type != null)
                {
                    ClientEdmModel edmModel = this.MaterializerContext.Model;
                    ClientTypeAnnotation complexType = edmModel.GetClientTypeAnnotation(edmModel.GetOrCreateEdmType(type));

                    // TODO: check if ComplexType inheritance will cause any issue
                    var complexInstance = this.ComplexValueMaterializationPolicy.CreateNewInstance(complexType.EdmTypeReference, complexType.ElementType);
                    this.ComplexValueMaterializationPolicy.MaterializeDataValues(complexType, complexValue.Properties, this.MaterializerContext.IgnoreMissingProperties);
                    this.ComplexValueMaterializationPolicy.ApplyDataValues(complexType, complexValue.Properties, complexInstance);
                    clrInstanceAnnotation = complexInstance;
                    return true;
                }

                return false;
            }

            var collectionValue = instanceAnnotation.Value as ODataCollectionValue;
            if (collectionValue != null)
            {
                var serverSideModel = this.MaterializerContext.Context.Format.LoadServiceModel();
                var valueTerm = serverSideModel.FindValueTerm(instanceAnnotation.Name);

                if (valueTerm != null && valueTerm.Type != null && valueTerm.Type.Definition != null)
                {
                    var edmCollectionType = valueTerm.Type.Definition as IEdmCollectionType;
                    if (edmCollectionType != null)
                    {
                        Type collectionItemType = null;
                        var elementType = edmCollectionType.ElementType;
                        PrimitiveType primitiveType;
                        if (PrimitiveType.TryGetPrimitiveType(elementType.FullName(), out primitiveType))
                        {
                            collectionItemType = primitiveType.ClrType;
                        }
                        else
                        {
                            collectionItemType = this.MaterializerContext.Context.ResolveTypeFromName(elementType.FullName());
                        }

                        if (collectionItemType != null)
                        {
                            Type collectionICollectionType = typeof(ICollection<>).MakeGenericType(new Type[] { collectionItemType });

                            ClientTypeAnnotation collectionClientTypeAnnotation = this.MaterializerContext.ResolveTypeForMaterialization(
                                collectionICollectionType,
                                collectionValue.TypeName);
                            bool isElementNullable = edmCollectionType.ElementType.IsNullable;

                            var collectionInstance = this.CollectionValueMaterializationPolicy.CreateCollectionInstance(
                                collectionClientTypeAnnotation.EdmTypeReference as IEdmCollectionTypeReference,
                                collectionClientTypeAnnotation.ElementType);
                            this.CollectionValueMaterializationPolicy.ApplyCollectionDataValues(
                                collectionValue.Items,
                                collectionValue.TypeName,
                                collectionInstance,
                                collectionItemType,
                                ClientTypeUtil.GetAddToCollectionDelegate(collectionICollectionType),
                                isElementNullable);
                            clrInstanceAnnotation = collectionInstance;
                            return true;
                        }
                    }
                }

                return false;
            }

            var nullValue = instanceAnnotation.Value as ODataNullValue;
            if (nullValue != null)
            {
                clrInstanceAnnotation = null;
                return true;
            }

            return false;
        }
        public void WriteInstanceAnnotationShouldPassPrimitiveTypeFromModelToUnderlyingWriter()
        {
            // Add a value term of type DateTimeOffset to the model.
            this.referencedModel.AddElement(new EdmTerm("My.Namespace", "DateTimeTerm", EdmPrimitiveTypeKind.DateTimeOffset));
            var instanceAnnotation = new ODataInstanceAnnotation("My.Namespace.DateTimeTerm", new ODataPrimitiveValue(DateTimeOffset.MinValue));

            bool calledWritePrimitive = false;

            this.valueWriter.WritePrimitiveVerifier = (o, reference) =>
            {
                reference.Should().NotBeNull();
                reference.IsDateTimeOffset().Should().BeTrue();
                calledWritePrimitive = true;
            };

            this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(instanceAnnotation);
            calledWritePrimitive.Should().BeTrue();
        }
 public void TheValuePropertyShouldReturnTheAnnotationValue()
 {
     foreach(ODataValue value in new ODataValue[] {new ODataNullValue(), new ODataPrimitiveValue(1), new ODataComplexValue(), new ODataCollectionValue()})
     {
         var annotation = new ODataInstanceAnnotation("namespace.name", value);
         annotation.Value.Should().BeSameAs(value);
     }
 }
 private static ODataInstanceAnnotation GetNextAnnotation(string namePrefix = null)
 {
     var annotation = new ODataInstanceAnnotation(GetNextName(namePrefix), GetNextValue());
     next++; 
     NextNameIndex++;
     return annotation;
 }