public WriterTypeNameEndToEndTests() { var model = new EdmModel(); var type = new EdmEntityType("TestModel", "TestEntity", /* baseType */ null, /* isAbstract */ false, /* isOpen */ true); var keyProperty = type.AddStructuralProperty("DeclaredInt16", EdmPrimitiveTypeKind.Int16); type.AddKeys(new[] { keyProperty }); // Note: DerivedPrimitive is declared as a Geography, but its value below will be set to GeographyPoint, which is derived from Geography. type.AddStructuralProperty("DerivedPrimitive", EdmPrimitiveTypeKind.Geography); var container = new EdmEntityContainer("TestModel", "Container"); var set = container.AddEntitySet("Set", type); model.AddElement(type); model.AddElement(container); var writerStream = new MemoryStream(); this.settings = new ODataMessageWriterSettings(); this.settings.SetServiceDocumentUri(ServiceDocumentUri); // Make the message writer and entry writer lazy so that individual tests can tweak the settings before the message writer is created. this.messageWriter = new Lazy<ODataMessageWriter>(() => new ODataMessageWriter( (IODataResponseMessage)new InMemoryMessage { Stream = writerStream }, this.settings, model)); var entryWriter = new Lazy<ODataWriter>(() => this.messageWriter.Value.CreateODataEntryWriter(set, type)); var valueWithAnnotation = new ODataPrimitiveValue(45); valueWithAnnotation.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = "TypeNameFromSTNA" }); var propertiesToWrite = new List<ODataProperty> { new ODataProperty { Name = "DeclaredInt16", Value = (Int16)42 }, new ODataProperty { Name = "UndeclaredDecimal", Value = (Decimal)4.5 }, new ODataProperty { // Note: value is more derived than the declared type. Name = "DerivedPrimitive", Value = Microsoft.Spatial.GeographyPoint.Create(42, 45) }, new ODataProperty() { Name = "PropertyWithSTNA", Value = valueWithAnnotation } }; this.writerOutput = new Lazy<string>(() => { entryWriter.Value.WriteStart(new ODataEntry { Properties = propertiesToWrite }); entryWriter.Value.WriteEnd(); entryWriter.Value.Flush(); writerStream.Seek(0, SeekOrigin.Begin); return new StreamReader(writerStream).ReadToEnd(); }); }
/// <summary> /// Determines if the given primitive value is of a basic type where we can rely on just the JSON representation to convey type information. /// If so, we don't have to write the type name. /// </summary> /// <param name="primitiveValue">The primitive value in question.</param> /// <param name="valueTypeReference">The type of the primitive value.</param> /// <returns>true if the given primitive value is of a basic JSON type, false otherwise.</returns> internal static bool ValueTypeMatchesJsonType(ODataPrimitiveValue primitiveValue, IEdmPrimitiveTypeReference valueTypeReference) { #if ODATALIB #endif switch (valueTypeReference.PrimitiveKind()) { // If the value being serialized is of a basic type where we can rely on just the JSON representation to convey type information, then never write the type name. case EdmPrimitiveTypeKind.Int32: case EdmPrimitiveTypeKind.String: case EdmPrimitiveTypeKind.Boolean: return true; case EdmPrimitiveTypeKind.Double: double doubleValue = (double)primitiveValue.Value; // If a double value is positive infinity, negative infinity, or NaN, we serialize the double as a string. // Thus the reader can't infer the type from the JSON representation, and we must write the type name explicitly // (i.e., if the property is open or the property type is assumed to be unknown, as is the case when writing in full metadata mode). return !IsDoubleValueSerializedAsString(doubleValue); default: return false; } }
internal static void AddTypeNameAnnotationAsNeeded(ODataPrimitiveValue primitive, ODataMetadataLevel metadataLevel) { Contract.Assert(primitive != null); object value = primitive.Value; // Don't add a type name annotation for Atom or JSON verbose. if (metadataLevel != ODataMetadataLevel.Default) { string typeName; if (ShouldSuppressTypeNameSerialization(value, metadataLevel)) { typeName = null; } else { typeName = GetTypeName(value); } primitive.SetAnnotation<SerializationTypeNameAnnotation>(new SerializationTypeNameAnnotation { TypeName = typeName }); } }
public void CreateODataValue_PrimitiveValue() { // Arrange IEdmPrimitiveTypeReference edmPrimitiveType = typeof(int).GetEdmPrimitiveTypeReference(); var serializer = new ODataPrimitiveSerializer(); // Act var odataValue = serializer.CreateODataValue(20, edmPrimitiveType, writeContext: null); // Assert Assert.NotNull(odataValue); ODataPrimitiveValue primitiveValue = Assert.IsType <ODataPrimitiveValue>(odataValue); Assert.Equal(20, primitiveValue.Value); }
public void AddTypeNameAnnotationAsNeeded_AddsAnnotation_InJsonLightMetadataMode() { // Arrange IEdmPrimitiveTypeReference edmPrimitiveType = EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(typeof(short)); ODataPrimitiveValue primitive = new ODataPrimitiveValue((short)1); // Act ODataPrimitiveSerializer.AddTypeNameAnnotationAsNeeded(primitive, edmPrimitiveType, ODataMetadataLevel.FullMetadata); // Assert ODataTypeAnnotation annotation = primitive.TypeAnnotation; Assert.NotNull(annotation); // Guard Assert.Equal("Edm.Int16", annotation.TypeName); }
public void CreateODataValue_ReturnsDateTimeOffset_ForDateTime_ByDefault() { // Arrange IEdmPrimitiveTypeReference edmPrimitiveType = typeof(DateTime).GetEdmPrimitiveTypeReference(); ODataPrimitiveSerializer serializer = new ODataPrimitiveSerializer(); DateTime dt = new DateTime(2014, 10, 27); // Act ODataValue odataValue = serializer.CreateODataValue(dt, edmPrimitiveType, new ODataSerializerContext()); // Assert ODataPrimitiveValue primitiveValue = Assert.IsType <ODataPrimitiveValue>(odataValue); Assert.Equal(new DateTimeOffset(dt), primitiveValue.Value); }
/// <inheritdoc/> public sealed override ODataValue CreateODataValue(object graph, IEdmTypeReference expectedType, ODataSerializerContext writeContext) { if (!expectedType.IsPrimitive()) { throw Error.InvalidOperation(SRResources.CannotWriteType, typeof(ODataPrimitiveSerializer), expectedType.FullName()); } ODataPrimitiveValue value = CreateODataPrimitiveValue(graph, expectedType.AsPrimitive(), writeContext); if (value == null) { return(new ODataNullValue()); } return(value); }
/// <summary> /// Writes a primitive property. /// </summary> /// <param name="property">The property to write out.</param> /// <param name="primitiveValue">The primitive value to be written</param> /// <param name="propertyTypeReference">The metadata type reference of the property.</param> /// <param name="isTopLevel">true when writing a top-level property; false for nested properties.</param> /// <param name="isOpenPropertyType">If the property is open.</param> private void WritePrimitiveProperty( ODataProperty property, ODataPrimitiveValue primitiveValue, IEdmTypeReference propertyTypeReference, bool isTopLevel, bool isOpenPropertyType) { string wirePropertyName = GetWirePropertyName(isTopLevel, property.Name); IEdmTypeReference typeFromValue = TypeNameOracle.ResolveAndValidateTypeForPrimitiveValue(primitiveValue); string typeNameToWrite = this.JsonLightOutputContext.TypeNameOracle.GetValueTypeNameForWriting(primitiveValue, propertyTypeReference, typeFromValue, isOpenPropertyType); this.WritePropertyTypeName(wirePropertyName, typeNameToWrite, isTopLevel); this.JsonWriter.WriteName(wirePropertyName); this.JsonLightValueSerializer.WritePrimitiveValue(primitiveValue.Value, propertyTypeReference); }
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); }); Assert.Contains("\"[email protected]\":\"#Date\",\"@sample.primitive\":\"2014-08-08\"", result); }
public override ODataFeed CreateODataFeed(IEnumerable feedInstance, IEdmCollectionTypeReference feedType, ODataSerializerContext writeContext) { ODataFeed feed = base.CreateODataFeed(feedInstance, feedType, writeContext); // Int32 ODataPrimitiveValue intValue = new ODataPrimitiveValue(321); feed.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.Int32Annotation", intValue)); // String ODataPrimitiveValue stringValue = new ODataPrimitiveValue("My amazing feed"); feed.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.StringAnnotation", stringValue)); return(feed); }
/// <summary> /// Converts an ODataValue to the old style of representing values, where null values are null and primitive values are just the direct primitive (no longer wrapped by ODataPrimitiveValue). /// All other value types, such as ODataCollectionValue are returned unchanged. /// </summary> /// <param name="odataValue">The value to convert.</param> /// <returns>The value behind the given ODataValue.</returns> internal static object FromODataValue(this ODataValue odataValue) { if (odataValue is ODataNullValue) { return(null); } ODataPrimitiveValue primitiveValue = odataValue as ODataPrimitiveValue; if (primitiveValue != null) { return(primitiveValue.Value); } return(odataValue); }
public static object GetInnerValue(this ODataValue odataValue) { if (odataValue is ODataNullValue) { return(null); } ODataPrimitiveValue oDataPrimitiveValue = odataValue as ODataPrimitiveValue; if (oDataPrimitiveValue != null) { return(oDataPrimitiveValue.Value); } return(odataValue); }
public void CreateODataValue_ReturnsTimeOfDay_ForTimeSpan() { // Arrange IEdmPrimitiveTypeReference edmPrimitiveType = typeof(TimeOfDay).GetEdmPrimitiveTypeReference(); ODataPrimitiveSerializer serializer = new ODataPrimitiveSerializer(); TimeSpan ts = new TimeSpan(0, 10, 11, 12, 13); // Act ODataValue odataValue = serializer.CreateODataValue(ts, edmPrimitiveType, new ODataSerializerContext()); // Assert ODataPrimitiveValue primitiveValue = Assert.IsType <ODataPrimitiveValue>(odataValue); Assert.IsType <TimeOfDay>(primitiveValue.Value); Assert.Equal(new TimeOfDay(ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds), primitiveValue.Value); }
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); }); Assert.Contains("\"[email protected]\":\"#TimeOfDay\",\"@sample.primitive\":\"12:30:05.0900000\"", result); }
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); }); Assert.Contains("\"[email protected]\":\"#DateTimeOffset\",\"@sample.primitive\":\"2000-01-01T12:30:00Z\"", result); }
public void CreateODataValue_ReturnsDate_ForDateTime() { // Arrange IEdmPrimitiveTypeReference edmPrimitiveType = EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(typeof(Date)); ODataPrimitiveSerializer serializer = new ODataPrimitiveSerializer(); DateTime dt = new DateTime(2014, 10, 27); // Act ODataValue odataValue = serializer.CreateODataValue(dt, edmPrimitiveType, new ODataSerializerContext()); // Assert ODataPrimitiveValue primitiveValue = Assert.IsType <ODataPrimitiveValue>(odataValue); Assert.IsType <Date>(primitiveValue.Value); Assert.Equal(new Date(dt.Year, dt.Month, dt.Day), primitiveValue.Value); }
public static void AssertODataValueAreEqual(ODataValue value1, ODataValue value2) { if (value1.IsNullValue && value2.IsNullValue) { return; } ODataPrimitiveValue primitiveValue1 = value1 as ODataPrimitiveValue; ODataPrimitiveValue primitiveValue2 = value2 as ODataPrimitiveValue; if (primitiveValue1 != null && primitiveValue2 != null) { AssertODataPrimitiveValueAreEqual(primitiveValue1, primitiveValue2); } else { ODataResourceValue resourceValue1 = value1 as ODataResourceValue; ODataResourceValue resourceValue2 = value2 as ODataResourceValue; if (resourceValue1 != null && resourceValue2 != null) { AssertODataResourceValueAreEqual(resourceValue1, resourceValue2); return; } ODataEnumValue enumValue1 = value1 as ODataEnumValue; ODataEnumValue enumValue2 = value2 as ODataEnumValue; if (enumValue1 != null && enumValue2 != null) { AssertODataEnumValueAreEqual(enumValue1, enumValue2); } else { ODataCollectionValue collectionValue1 = value1 as ODataCollectionValue; ODataCollectionValue collectionValue2 = value2 as ODataCollectionValue; if (collectionValue1 != null && collectionValue2 != null) { AssertODataCollectionValueAreEqual(collectionValue1, collectionValue2); } else { ODataUntypedValue untyped1 = value1 as ODataUntypedValue; ODataUntypedValue untyped2 = value2 as ODataUntypedValue; Assert.Equal(untyped1.RawValue, untyped2.RawValue); } } } }
/// <summary> /// Visits a primitive value. /// </summary> /// <param name="primitiveValue">The primitive value to visit.</param> protected override ODataPayloadElement VisitPrimitiveValue(object primitiveValue) { if (primitiveValue == null) { return(new PrimitiveValue(null, null)); } else { ODataPrimitiveValue odataPrimitiveValue = primitiveValue as ODataPrimitiveValue; if (odataPrimitiveValue != null) { primitiveValue = odataPrimitiveValue.Value; } return(new PrimitiveValue(EntityModelUtils.GetPrimitiveEdmType(primitiveValue.GetType()).FullEdmName(), primitiveValue)); } }
public override ODataPrimitiveValue CreateODataPrimitiveValue(object graph, IEdmPrimitiveTypeReference primitiveType, ODataSerializerContext writeContext) { ODataPrimitiveValue result = base.CreateODataPrimitiveValue(graph, primitiveType, writeContext); if (result?.Value is DateTimeOffset date) { IDependencyResolver dependencyResolver = writeContext.Request.GetOwinContext() .GetDependencyResolver(); ITimeZoneManager timeZoneManager = dependencyResolver.Resolve <ITimeZoneManager>(); result = new ODataPrimitiveValue(timeZoneManager.MapFromServerToClient(date)); } return(result); }
public void WriteTopLevelErrorWithStringInstanceAnnotationWithTypeNameAttribute() { var result = SetupSerializerAndRunTest(null, serializer => { ODataError error = new ODataError(); var instanceAnnotations = new Collection <ODataInstanceAnnotation>(); var primitiveValue = new ODataPrimitiveValue("stringValue"); primitiveValue.TypeAnnotation = new ODataTypeAnnotation("Custom.Type"); ODataInstanceAnnotation annotation = new ODataInstanceAnnotation("sample.primitive", primitiveValue); instanceAnnotations.Add(annotation); error.InstanceAnnotations = instanceAnnotations; serializer.WriteTopLevelError(error, false); }); Assert.Contains("\"[email protected]\":\"#Custom.Type\",\"@sample.primitive\":\"stringValue\"", result); }
/// <summary> /// Gets the metadata URI type name based on the given property. /// </summary> /// <param name="property">The property.</param> /// <returns>The type name for the metadata URI.</returns> private static string GetMetadataUriTypeNameForValue(ODataProperty property) { Debug.Assert(property != null, "property != null"); ODataValue value = property.ODataValue; Debug.Assert(value != null, "value != null"); // special identifier for null values. if (value.IsNullValue) { return(JsonLightConstants.MetadataUriFragmentNull); } var typeAnnotation = value.GetAnnotation <SerializationTypeNameAnnotation>(); if (typeAnnotation != null && !string.IsNullOrEmpty(typeAnnotation.TypeName)) { return(typeAnnotation.TypeName); } var complexValue = value as ODataComplexValue; if (complexValue != null) { return(complexValue.TypeName); } var collectionValue = value as ODataCollectionValue; if (collectionValue != null) { return(collectionValue.TypeName); } ODataPrimitiveValue primitive = value as ODataPrimitiveValue; if (primitive == null) { Debug.Assert(value is ODataStreamReferenceValue, "value is ODataStreamReferenceValue"); throw new ODataException(OData.Strings.ODataWriter_StreamPropertiesMustBePropertiesOfODataEntry(property.Name)); } return(EdmLibraryExtensions.GetPrimitiveTypeReference(primitive.Value.GetType()).ODataFullName()); }
internal static ODataPrimitiveValue CreatePrimitive(object value, IEdmPrimitiveTypeReference primitiveType, ODataSerializerContext writeContext) { if (value == null) { return(null); } object supportedValue = ConvertPrimitiveValue(value, primitiveType); ODataPrimitiveValue primitive = new ODataPrimitiveValue(supportedValue); if (writeContext != null) { AddTypeNameAnnotationAsNeeded(primitive, primitiveType, writeContext.MetadataLevel); } return(primitive); }
/// <summary> /// Converts an ODataValue to the old style of representing values, where null values are null and primitive values are just the direct primitive (no longer wrapped by ODataPrimitiveValue). /// All other value types, such as ODataComplexValue and ODataCollectionValue are returned unchanged. /// </summary> /// <param name="odataValue">The value to convert.</param> /// <returns>The value behind the given ODataValue.</returns> internal static object FromODataValue(this ODataValue odataValue) { DebugUtils.CheckNoExternalCallers(); if (odataValue is ODataNullValue) { return(null); } ODataPrimitiveValue primitiveValue = odataValue as ODataPrimitiveValue; if (primitiveValue != null) { return(primitiveValue.Value); } return(odataValue); }
internal static void AddTypeNameAnnotationAsNeeded(ODataPrimitiveValue primitive, IEdmPrimitiveTypeReference primitiveType, ODataMetadataLevel metadataLevel) { // ODataLib normally has the caller decide whether or not to serialize properties by leaving properties // null when values should not be serialized. The TypeName property is different and should always be // provided to ODataLib to enable model validation. A separate annotation is used to decide whether or not // to serialize the type name (a null value prevents serialization). Contract.Assert(primitive != null); object value = primitive.Value; string typeName = null; // Set null to force the type name not to serialize. // Provide the type name to serialize. if (!ShouldSuppressTypeNameSerialization(value, metadataLevel)) { typeName = primitiveType.FullName(); } primitive.TypeAnnotation = new ODataTypeAnnotation(typeName); }
public ODataResource CreateEntry(Object entity) { for (int i = 0; i < _accessors.Length; i++) { OePropertyAccessor accessor = _accessors[i]; Object value = accessor.Accessor(entity); if (value is DateTime) { value = (DateTimeOffset)(DateTime)value; } ODataValue odataValue = null; if (value == null) { odataValue = new ODataNullValue() { TypeAnnotation = accessor.TypeAnnotation } } ; else { if (value.GetType().GetTypeInfo().IsEnum) { odataValue = new ODataEnumValue(value.ToString()); } else { odataValue = new ODataPrimitiveValue(value); } odataValue.TypeAnnotation = accessor.TypeAnnotation; } _odataProperties[i].Value = odataValue; } return(new ODataResource { TypeName = _typeName, Properties = _odataProperties }); }
public void WriteInstanceAnnotation_ForDateShouldUsePrimitiveCodePathWithTypeName() { var date = new ODataPrimitiveValue(new Date(2014, 11, 11)); const string term = "some.term"; var verifierCalls = 0; this.jsonWriter.WriteNameVerifier = (name) => { if (verifierCalls == 0) { Assert.Equal(term + "@odata.type", name); verifierCalls++; } else if (verifierCalls == 2) { Assert.Equal("@" + term, name); verifierCalls++; } else { throw new Exception("unexpected call to JsonWriter.WriteName"); } }; this.jsonWriter.WriteValueVerifier = (value) => { Assert.Equal(1, verifierCalls); verifierCalls++; }; this.valueWriter.WritePrimitiveVerifier = (value, reference) => { Assert.Equal(date.Value, value); Assert.Null(reference); Assert.Equal(3, verifierCalls); verifierCalls++; }; this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(new ODataInstanceAnnotation(term, date)); Assert.Equal(4, verifierCalls); }
public void WriteInstanceAnnotation_ForTimeOfDayShouldUsePrimitiveCodePathWithTypeName() { var time = new ODataPrimitiveValue(new TimeOfDay(12, 5, 0, 90)); const string term = "some.term"; var verifierCalls = 0; this.jsonWriter.WriteNameVerifier = (name) => { if (verifierCalls == 0) { name.Should().Be(term + "@odata.type"); verifierCalls++; } else if (verifierCalls == 2) { name.Should().Be("@" + term); verifierCalls++; } else { throw new Exception("unexpected call to JsonWriter.WriteName"); } }; this.jsonWriter.WriteValueVerifier = (value) => { verifierCalls.Should().Be(1); verifierCalls++; }; this.valueWriter.WritePrimitiveVerifier = (value, reference) => { value.Should().Be(time.Value); reference.Should().BeNull(); verifierCalls.Should().Be(3); verifierCalls++; }; this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(new ODataInstanceAnnotation(term, time)); verifierCalls.Should().Be(4); }
public static void AssertODataValueAreEqual(ODataValue value1, ODataValue value2) { if (value1.IsNullValue && value2.IsNullValue) { return; } ODataPrimitiveValue primitiveValue1 = value1 as ODataPrimitiveValue; ODataPrimitiveValue primitiveValue2 = value2 as ODataPrimitiveValue; if (primitiveValue1 != null && primitiveValue2 != null) { AssertODataPrimitiveValueAreEqual(primitiveValue1, primitiveValue2); } else { ODataComplexValue complexValue1 = value1 as ODataComplexValue; ODataComplexValue complexValue2 = value2 as ODataComplexValue; if (complexValue1 != null && complexValue2 != null) { AssertODataComplexValueAreEqual(complexValue1, complexValue2); } else { ODataEnumValue enumValue1 = value1 as ODataEnumValue; ODataEnumValue enumValue2 = value2 as ODataEnumValue; if (enumValue1 != null && enumValue2 != null) { AssertODataEnumValueAreEqual(enumValue1, enumValue2); } else { ODataCollectionValue collectionValue1 = (ODataCollectionValue)value1; ODataCollectionValue collectionValue2 = (ODataCollectionValue)value2; AssertODataCollectionValueAreEqual(collectionValue1, collectionValue2); } } } }
public void WriteInstanceAnnotation_ForIntegerShouldUsePrimitiveCodePath() { var integerValue = new ODataPrimitiveValue(123); const string term = "some.term"; var verifierCalls = 0; this.jsonWriter.WriteNameVerifier = (name) => { Assert.Equal("@" + term, name); verifierCalls++; }; this.valueWriter.WritePrimitiveVerifier = (value, reference) => { Assert.Equal(integerValue.Value, value); Assert.Null(reference); Assert.Equal(1, verifierCalls); verifierCalls++; }; this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(new ODataInstanceAnnotation(term, integerValue)); Assert.Equal(2, verifierCalls); }
public void WriteInstanceAnnotation_ForSpatialShouldUsePrimitiveCodePathWithTypeName() { var point = new ODataPrimitiveValue(GeographyPoint.Create(10.5, 5.25)); const string term = "some.term"; var verifierCalls = 0; this.jsonWriter.WriteNameVerifier = (name) => { if (verifierCalls == 0) { name.Should().Be(term + "@odata.type"); verifierCalls++; } else if (verifierCalls == 2) { name.Should().Be("@" + term); verifierCalls++; } else { throw new Exception("unexpected call to JsonWriter.WriteName"); } }; this.jsonWriter.WriteValueVerifier = (value) => { verifierCalls.Should().Be(1); verifierCalls++; }; this.valueWriter.WritePrimitiveVerifier = (value, reference) => { value.Should().Be(point.Value); reference.Should().BeNull(); verifierCalls.Should().Be(3); verifierCalls++; }; this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(new ODataInstanceAnnotation(term, point)); verifierCalls.Should().Be(4); }
public void WriteInstanceAnnotation_ForIntegerShouldUsePrimitiveCodePath() { var integerValue = new ODataPrimitiveValue(123); const string term = "some.term"; var verifierCalls = 0; this.jsonWriter.WriteNameVerifier = (name) => { name.Should().Be("@" + term); verifierCalls++; }; this.valueWriter.WritePrimitiveVerifier = (value, reference) => { value.Should().Be(integerValue.Value); reference.Should().BeNull(); verifierCalls.Should().Be(1); verifierCalls++; }; this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(new ODataInstanceAnnotation(term, integerValue)); verifierCalls.Should().Be(2); }
/// <summary> /// Writes the value of a primitive instance annotation. /// </summary> /// <param name="primitiveValue">The primitive value to write.</param> /// <param name="expectedTypeReference">The expected type of the annotation from the metadata.</param> private void WritePrimitiveInstanceAnnotationValue(ODataPrimitiveValue primitiveValue, IEdmTypeReference expectedTypeReference) { object clrValue = primitiveValue.Value; IEdmPrimitiveTypeReference primitiveTypeReference = EdmLibraryExtensions.GetPrimitiveTypeReference(clrValue.GetType()); string attributeValueNotationName = AtomInstanceAnnotation.LookupAttributeValueNotationNameByEdmTypeKind(primitiveTypeReference.PrimitiveKind()); // Some primitive values can be specified more concisely via an attribute rather than in the content of the xml element. This is called "attribute value notation". // If we're writing a type that supports this, then we always prefer attribute value notation over writing the value in the element content. if (attributeValueNotationName != null) { if (expectedTypeReference != null) { ValidationUtils.ValidateIsExpectedPrimitiveType(primitiveValue.Value, primitiveTypeReference, expectedTypeReference); } this.XmlWriter.WriteAttributeString(attributeValueNotationName, AtomValueUtils.ConvertPrimitiveToString(clrValue)); } else { this.WritePrimitiveValue(clrValue, /*collectionValidator*/ null, expectedTypeReference, primitiveValue.GetAnnotation <SerializationTypeNameAnnotation>()); } }
internal static bool ValueTypeMatchesJsonType(ODataPrimitiveValue primitiveValue, EdmPrimitiveTypeKind primitiveTypeKind) { switch (primitiveTypeKind) { // If the value being serialized is of a basic type where we can rely on just the JSON representation to convey type information, then never write the type name. case EdmPrimitiveTypeKind.Int32: case EdmPrimitiveTypeKind.String: case EdmPrimitiveTypeKind.Boolean: return(true); case EdmPrimitiveTypeKind.Double: double doubleValue = (double)primitiveValue.Value; // If a double value is positive infinity, negative infinity, or NaN, we serialize the double as a string. // Thus the reader can't infer the type from the JSON representation, and we must write the type name explicitly // (i.e., if the property is open or the property type is assumed to be unknown, as is the case when writing in full metadata mode). return(!IsDoubleValueSerializedAsString(doubleValue)); default: return(false); } }
internal static void AddTypeNameAnnotationAsNeeded(ODataPrimitiveValue primitive, ODataMetadataLevel metadataLevel) { // ODataLib normally has the caller decide whether or not to serialize properties by leaving properties // null when values should not be serialized. The TypeName property is different and should always be // provided to ODataLib to enable model validation. A separate annotation is used to decide whether or not // to serialize the type name (a null value prevents serialization). // Note that this annotation should not be used for Atom or JSON verbose formats, as it will interfere with // the correct default behavior for those formats. Contract.Assert(primitive != null); object value = primitive.Value; // Only add an annotation if we want to override ODataLib's default type name serialization behavior. if (ShouldAddTypeNameAnnotation(metadataLevel)) { string typeName; // Provide the type name to serialize (or null to force it not to serialize). if (ShouldSuppressTypeNameSerialization(value, metadataLevel)) { typeName = null; } else { typeName = GetTypeName(value); } primitive.SetAnnotation<SerializationTypeNameAnnotation>(new SerializationTypeNameAnnotation { TypeName = typeName }); } }
public void AddTypeNameAnnotationAsNeeded_DoesNotAddAnnotation_InDefaultMetadataMode() { // Arrange ODataPrimitiveValue primitive = new ODataPrimitiveValue(0); // Act ODataPrimitiveSerializer.AddTypeNameAnnotationAsNeeded(primitive, ODataMetadataLevel.Default); // Assert Assert.Null(primitive.GetAnnotation<SerializationTypeNameAnnotation>()); }
public void PrimitiveValueShouldSupportUInt64() { ODataPrimitiveValue valueUInt64 = new ODataPrimitiveValue((UInt64)123); this.property.Value = valueUInt64; this.property.ODataValue.Should().BeSameAs(valueUInt64); }
public void IfValueIsODataPrimitiveValueThenODataValueShouldBeReferenceEqual() { ODataPrimitiveValue primitiveValue = new ODataPrimitiveValue(42); this.property.Value = primitiveValue; this.property.ODataValue.Should().BeSameAs(primitiveValue); }
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\""); }
internal static ODataValue CreatePrimitive(object value, ODataMetadataLevel metadataLevel) { if (value == null) { return new ODataNullValue(); } object supportedValue = ConvertUnsupportedPrimitives(value); ODataPrimitiveValue primitive = new ODataPrimitiveValue(supportedValue); AddTypeNameAnnotationAsNeeded(primitive, metadataLevel); return primitive; }
public void BuildPropertyContextUriForIntegerPropertyValueWithNonNullAnnotation() { ODataValue value = new ODataPrimitiveValue(1); value.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = "FQNS.FromAnnotation" }); var contextUri = this.CreatePropertyContextUri(value); contextUri.OriginalString.Should().Be(BuildExpectedContextUri("#FQNS.FromAnnotation")); }
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 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 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 AddTypeNameAnnotationAsNeeded_DoesNotAddAnnotation_InDefaultMetadataMode() { // Arrange IEdmPrimitiveTypeReference edmPrimitiveType = EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(typeof(int)); ODataPrimitiveValue primitive = new ODataPrimitiveValue(0); // Act ODataPrimitiveSerializer.AddTypeNameAnnotationAsNeeded(primitive, edmPrimitiveType, ODataMetadataLevel.Default); // Assert Assert.Null(primitive.GetAnnotation<SerializationTypeNameAnnotation>()); }
/// <summary> /// Writes the value of a primitive instance annotation. /// </summary> /// <param name="primitiveValue">The primitive value to write.</param> /// <param name="expectedTypeReference">The expected type of the annotation from the metadata.</param> private void WritePrimitiveInstanceAnnotationValue(ODataPrimitiveValue primitiveValue, IEdmTypeReference expectedTypeReference) { object clrValue = primitiveValue.Value; IEdmPrimitiveTypeReference primitiveTypeReference = EdmLibraryExtensions.GetPrimitiveTypeReference(clrValue.GetType()); string attributeValueNotationName = AtomInstanceAnnotation.LookupAttributeValueNotationNameByEdmTypeKind(primitiveTypeReference.PrimitiveKind()); // Some primitive values can be specified more concisely via an attribute rather than in the content of the xml element. This is called "attribute value notation". // If we're writing a type that supports this, then we always prefer attribute value notation over writing the value in the element content. if (attributeValueNotationName != null) { if (expectedTypeReference != null) { ValidationUtils.ValidateIsExpectedPrimitiveType(primitiveValue.Value, primitiveTypeReference, expectedTypeReference); } this.XmlWriter.WriteAttributeString(attributeValueNotationName, AtomValueUtils.ConvertPrimitiveToString(clrValue)); } else { this.WritePrimitiveValue(clrValue, /*collectionValidator*/ null, expectedTypeReference, primitiveValue.GetAnnotation<SerializationTypeNameAnnotation>()); } }
public void AddTypeNameAnnotationAsNeeded_AddsAnnotation_InJsonLightMetadataMode() { // Arrange IEdmPrimitiveTypeReference edmPrimitiveType = EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(typeof(short)); ODataPrimitiveValue primitive = new ODataPrimitiveValue((short)1); // Act ODataPrimitiveSerializer.AddTypeNameAnnotationAsNeeded(primitive, edmPrimitiveType, ODataMetadataLevel.FullMetadata); // Assert SerializationTypeNameAnnotation annotation = primitive.GetAnnotation<SerializationTypeNameAnnotation>(); Assert.NotNull(annotation); // Guard Assert.Equal("Edm.Int16", annotation.TypeName); }
public void TypeNameShouldComeFromSerializationTypeNameAnnotationForPrimitiveValue() { var stna = new SerializationTypeNameAnnotation() {TypeName = "FromSTNA"}; var value = new ODataPrimitiveValue(42); value.SetAnnotation(stna); this.typeNameOracle.GetValueTypeNameForWriting(value, EdmCoreModel.Instance.GetInt32(true), EdmCoreModel.Instance.GetInt32(false), /* isOpenProperty*/ false).Should().Be("FromSTNA"); }
public void CreatingNestedODataPrimitiveValueShouldFail() { ODataPrimitiveValue innerPrimitiveValue = new ODataPrimitiveValue(42); Action testSubject = () => new ODataPrimitiveValue(innerPrimitiveValue); testSubject.ShouldThrow<ODataException>().WithMessage(ErrorStrings.ODataPrimitiveValue_CannotCreateODataPrimitiveValueFromUnsupportedValueType("Microsoft.OData.Core.ODataPrimitiveValue")); }