Ejemplo n.º 1
0
        /// <summary>
        /// Resolves and validates the Edm type for the given <paramref name="value"/>.
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeReferenceFromMetadata">The type inferred from the model or null if the model is not a user model.</param>
        /// <param name="value">The value in question to resolve the type for.</param>
        /// <param name="isOpenProperty">true if the type name belongs to an open property, false otherwise.</param>
        /// <returns>A type for the <paramref name="value"/> or null if no metadata is available.</returns>
        internal static IEdmTypeReference ResolveAndValidateTypeNameForValue(IEdmModel model, IEdmTypeReference typeReferenceFromMetadata, ODataValue value, bool isOpenProperty)
        {
            Debug.Assert(model != null, "model != null");
            Debug.Assert(value != null, "value != null");

            ODataPrimitiveValue primitiveValue = value as ODataPrimitiveValue;
            if (primitiveValue != null)
            {
                Debug.Assert(primitiveValue.Value != null, "primitiveValue.Value != null");
                return EdmLibraryExtensions.GetPrimitiveTypeReference(primitiveValue.Value.GetType());
            }

            ODataComplexValue complexValue = value as ODataComplexValue;
            if (complexValue != null)
            {
                return ResolveAndValidateTypeFromNameAndMetadata(model, typeReferenceFromMetadata, complexValue.TypeName, EdmTypeKind.Complex, isOpenProperty);
            }

            ODataEnumValue enumValue = value as ODataEnumValue;
            if (enumValue != null)
            {
                return ResolveAndValidateTypeFromNameAndMetadata(model, typeReferenceFromMetadata, enumValue.TypeName, EdmTypeKind.Enum, isOpenProperty);
            }

            ODataCollectionValue collectionValue = (ODataCollectionValue)value;
            return ResolveAndValidateTypeFromNameAndMetadata(model, typeReferenceFromMetadata, collectionValue.TypeName, EdmTypeKind.Collection, isOpenProperty);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Constructs a new <see cref="ODataInstanceAnnotation"/> instance.
 /// </summary>
 /// <param name="name">The name of the instance annotation.</param>
 /// <param name="value">The value of the instance annotation.</param>
 public ODataInstanceAnnotation(string name, ODataValue value)
 {
     ValidateName(name);
     ValidateValue(value);
     this.Name = name;
     this.Value = value;
 }
 public static void AssertODataValueAreEqual(ODataValue expected, ODataValue actual)
 {
     ODataPrimitiveValue expectedPrimitiveValue = expected as ODataPrimitiveValue;
     ODataPrimitiveValue actualPrimitiveValue = actual as ODataPrimitiveValue;
     if (expectedPrimitiveValue != null && actualPrimitiveValue != null)
     {
         AssertODataPrimitiveValueAreEqual(expectedPrimitiveValue, actualPrimitiveValue);
     }
     else
     {
         ODataComplexValue expectedComplexValue = expected as ODataComplexValue;
         ODataComplexValue actualComplexValue = actual as ODataComplexValue;
         if (expectedComplexValue != null && actualComplexValue != null)
         {
             AssertODataComplexValueAreEqual(expectedComplexValue, actualComplexValue);
         }
         else
         {
             ODataEnumValue expectedEnumValue = expected as ODataEnumValue;
             ODataEnumValue actualEnumValue = actual as ODataEnumValue;
             if (expectedEnumValue != null && actualEnumValue != null)
             {
                 AssertODataEnumValueAreEqual(expectedEnumValue, actualEnumValue);
             }
             else
             {
                 ODataCollectionValue expectedCollectionValue = (ODataCollectionValue)expected;
                 ODataCollectionValue actualCollectionValue = (ODataCollectionValue)actual;
                 AssertODataCollectionValueAreEqual(expectedCollectionValue, actualCollectionValue);
             }
         }
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Validates the given <paramref name="value"/> is a valid instance annotation value.
        /// </summary>
        /// <param name="value">Value to validate.</param>
        internal static void ValidateValue(ODataValue value)
        {
            ExceptionUtils.CheckArgumentNotNull(value, "value");

            if (value is ODataStreamReferenceValue)
            {
                throw new ArgumentException(Strings.ODataInstanceAnnotation_ValueCannotBeODataStreamReferenceValue, "value");
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Gets the type name based on the given odata value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="model">The model used to handle unsigned int conversions.</param>
        /// <returns>The type name for the context URI.</returns>
        private static string GetTypeNameForValue(ODataValue value, IEdmModel model)
        {
            if (value == null)
            {
                return(null);
            }

            // special identifier for null values.
            if (value.IsNullValue)
            {
                return(ODataConstants.ContextUriFragmentNull);
            }

            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(EdmLibraryExtensions.GetCollectionTypeFullName(collectionValue.TypeName));
            }

            var enumValue = value as ODataEnumValue;

            if (enumValue != null)
            {
                return(enumValue.TypeName);
            }

            ODataPrimitiveValue primitive = value as ODataPrimitiveValue;

            if (primitive == null)
            {
                Debug.Assert(value is ODataStreamReferenceValue, "value is ODataStreamReferenceValue");
                throw new ODataException(Strings.ODataContextUriBuilder_StreamValueMustBePropertiesOfODataEntry);
            }

            // Try convert to underlying type if the primitive value is unsigned int.
            IEdmTypeDefinitionReference typeDefinitionReference = model.ResolveUIntTypeDefinition(primitive.Value);

            if (typeDefinitionReference != null)
            {
                return(typeDefinitionReference.ODataFullName());
            }

            IEdmPrimitiveTypeReference primitiveValueTypeReference = EdmLibraryExtensions.GetPrimitiveTypeReference(primitive.Value.GetType());

            return(primitiveValueTypeReference == null ? null : primitiveValueTypeReference.ODataFullName());
        }
        internal void SetTypeName(ODataValue value, ResourceType actualType)
        {
            Debug.Assert(value != null, "value != null");

#if DEBUG
            var complexValue = value as ODataComplexValue;
            if (complexValue != null)
            {
                Debug.Assert(!String.IsNullOrEmpty(complexValue.TypeName), "Type name must be specified in ODataComplexValue since ODL needs it for validation.");
            }
            else
            {
                var collectionValue = value as ODataCollectionValue;
                Debug.Assert(collectionValue == null || !String.IsNullOrEmpty(collectionValue.TypeName), "Type name must be specified in ODataCollectionValue since ODL needs it for validation.");
            }
#endif
            string typeNameToWrite;
            if (this.interpreter.ShouldSpecifyTypeNameAnnotation(value, actualType, out typeNameToWrite))
            {
                value.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = typeNameToWrite });
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Resolves and validates the Edm type for the given <paramref name="value"/>.
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeReferenceFromMetadata">The type inferred from the model or null if the model is not a user model.</param>
        /// <param name="value">The value in question to resolve the type for.</param>
        /// <param name="isOpenProperty">true if the type name belongs to an open property, false otherwise.</param>
        /// <returns>A type for the <paramref name="value"/> or null if no metadata is available.</returns>
        internal static IEdmTypeReference ResolveAndValidateTypeNameForValue(IEdmModel model, IEdmTypeReference typeReferenceFromMetadata, ODataValue value, bool isOpenProperty)
        {
            Debug.Assert(model != null, "model != null");
            Debug.Assert(value != null, "value != null");

            ODataPrimitiveValue primitiveValue = value as ODataPrimitiveValue;

            if (primitiveValue != null)
            {
                Debug.Assert(primitiveValue.Value != null, "primitiveValue.Value != null");
                return(EdmLibraryExtensions.GetPrimitiveTypeReference(primitiveValue.Value.GetType()));
            }

            ODataComplexValue complexValue = value as ODataComplexValue;

            if (complexValue != null)
            {
                return(ResolveAndValidateTypeFromNameAndMetadata(model, typeReferenceFromMetadata, complexValue.TypeName, EdmTypeKind.Complex, isOpenProperty));
            }

            ODataEnumValue enumValue = value as ODataEnumValue;

            if (enumValue != null)
            {
                return(ResolveAndValidateTypeFromNameAndMetadata(model, typeReferenceFromMetadata, enumValue.TypeName, EdmTypeKind.Enum, isOpenProperty));
            }

            ODataCollectionValue collectionValue = (ODataCollectionValue)value;

            return(ResolveAndValidateTypeFromNameAndMetadata(model, typeReferenceFromMetadata, collectionValue.TypeName, EdmTypeKind.Collection, isOpenProperty));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Adds a type annotation to the value if it is primitive and not defined on the server.
        /// </summary>
        /// <param name="serverTypeName">The server type name of the entity whose properties are being populated.</param>
        /// <param name="property">The current property.</param>
        /// <param name="odataValue">The already converted value of the property.</param>
        private void AddTypeAnnotationNotDeclaredOnServer(string serverTypeName, ClientPropertyAnnotation property, ODataValue odataValue)
        {
            Debug.Assert(property != null, "property != null");
            Debug.Assert(property.EdmProperty != null, "property.EdmProperty != null");
            var primitiveValue = odataValue as ODataPrimitiveValue;
            if (primitiveValue == null)
            {
                return;
            }

            if (!this.requestInfo.Format.UsingAtom
                && this.requestInfo.TypeResolver.ShouldWriteClientTypeForOpenServerProperty(property.EdmProperty, serverTypeName)
                && !JsonSharedUtils.ValueTypeMatchesJsonType(primitiveValue, property.EdmProperty.Type.AsPrimitive()))
            {
                // DEVNOTE: it is safe to use the property type name for primitive types because they do not generally support inheritance,
                // and spatial values always contain their specific type inside the GeoJSON/GML representation.
                primitiveValue.SetAnnotation(new SerializationTypeNameAnnotation { TypeName = property.EdmProperty.Type.FullName() });
            }
        }
Ejemplo n.º 9
0
        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);
                    }
                }
            }
        }
 private Uri CreateIndividualPropertyContextUri(ODataValue value, string resourcePath)
 {
     ODataContextUrlInfo info = ODataContextUrlInfo.Create(value, new ODataUri() { Path = new ODataUriParser(edmModel, new Uri(ServiceDocumentUriString), new Uri(ServiceDocumentUriString + resourcePath)).ParsePath() });
     Uri contextUrl = this.responseContextUriBuilder.BuildContextUri(ODataPayloadKind.IndividualProperty, info);
     contextUrl.Should().NotBeNull();
     return contextUrl;
 }
 public void GetInnerValue_Returns_CorrectObject(ODataValue value, object expectedResult)
 {
     Assert.Equal(expectedResult, value.GetInnerValue());
 }
        /// <summary>
        /// Returns whether ODataLib should be explicitly instructed to include or omit a type name on the wire.
        /// </summary>
        /// <param name="value">The value to be serialized.</param>
        /// <param name="actualType">The type to be potentially serialized.</param>
        /// <param name="typeNameToWrite">The type name which ODataLib should be told to serialize. A value of null indicates the type name should be omitted.</param>
        /// <returns>true if an annotation should be created to override ODataLib's default type name serialization behavior; false if the ODataLib default behavior should be used.</returns>
        internal bool ShouldSpecifyTypeNameAnnotation(ODataValue value, ResourceType actualType, out string typeNameToWrite)
        {
            if (this.metadataParameterValueForTypeNames == MetadataParameterValue.Full)
            {
                ODataPrimitiveValue primitiveValue = value as ODataPrimitiveValue;
                Debug.Assert(primitiveValue == null || actualType.ResourceTypeKind == ResourceTypeKind.Primitive, "If value is ODataPrimitiveValue, actualType must also be primitive.");
                if (primitiveValue != null && JsonSharedUtils.ValueTypeMatchesJsonType(primitiveValue, MetadataProviderUtils.CreatePrimitiveTypeReference(actualType)))
                {
                    // Don't set the annotation and use the default ODataLib type name serialization behavior for basic JSON types.
                    typeNameToWrite = null;
                    return false;
                }

                typeNameToWrite = actualType.FullName;
                return true;
            }

            if (this.metadataParameterValueForTypeNames == MetadataParameterValue.None)
            {
                // Setting the type name to null explicitly tells ODataLib to not write a type name annotation on the wire.
                typeNameToWrite = null;
                return true;
            }

            // Otherwise, don't set the annotation and use the default ODataLib type name serialization behavior.
            typeNameToWrite = null;
            return false;
        }
Ejemplo n.º 13
0
 protected internal ODataValueAssertions(ODataValue value) 
     : base(value)
 {
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Create ODataContextUrlInfo for OdataValue.
 /// </summary>
 /// <param name="value">The ODataValue to be used.</param>
 /// <param name="odataUri">The odata uri info for current query.</param>
 /// <param name="model">The model used to handle unsigned int conversions.</param>
 /// <returns>The generated ODataContextUrlInfo.</returns>
 internal static ODataContextUrlInfo Create(ODataValue value, ODataUri odataUri = null, IEdmModel model = null)
 {
     return new ODataContextUrlInfo()
     {
         TypeName = GetTypeNameForValue(value, model),
         odataUri = odataUri
     };
 }
Ejemplo n.º 15
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);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Gets the type name based on the given odata value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="model">The model used to handle unsigned int conversions.</param>
        /// <returns>The type name for the context URI.</returns>
        private static string GetTypeNameForValue(ODataValue value, IEdmModel model)
        {
            if (value == null)
            {
                return null;
            }

            // special identifier for null values.
            if (value.IsNullValue)
            {
                return ODataConstants.ContextUriFragmentNull;
            }

            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 EdmLibraryExtensions.GetCollectionTypeFullName(collectionValue.TypeName);
            }

            var enumValue = value as ODataEnumValue;
            if (enumValue != null)
            {
                return enumValue.TypeName;
            }

            var untypedValue = value as ODataUntypedValue;
            if (untypedValue != null)
            {
                return ODataConstants.ContextUriFragmentUntyped;
            }

            ODataPrimitiveValue primitive = value as ODataPrimitiveValue;
            if (primitive == null)
            {
                Debug.Assert(value is ODataStreamReferenceValue, "value is ODataStreamReferenceValue");
                throw new ODataException(Strings.ODataContextUriBuilder_StreamValueMustBePropertiesOfODataEntry);
            }

            // Try convert to underlying type if the primitive value is unsigned int.
            IEdmTypeDefinitionReference typeDefinitionReference = model.ResolveUIntTypeDefinition(primitive.Value);
            if (typeDefinitionReference != null)
            {
                return typeDefinitionReference.FullName();
            }

            IEdmPrimitiveTypeReference primitiveValueTypeReference = EdmLibraryExtensions.GetPrimitiveTypeReference(primitive.Value.GetType());
            return primitiveValueTypeReference == null ? null : primitiveValueTypeReference.FullName();
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Tries to convert the given value into an instance of <see cref="ODataValue"/>.
        /// </summary>
        /// <param name="property">The property being converted.</param>
        /// <param name="propertyValue">The property value to convert..</param>
        /// <param name="serverTypeName">The server type name of the entity whose properties are being populated.</param>
        /// <param name="visitedComplexTypeObjects">Set of instances of complex types encountered in the hierarchy. Used to detect cycles.</param>
        /// <param name="odataValue">The odata value if one was created.</param>
        /// <returns>Whether or not the value was converted.</returns>
        private bool TryConvertPropertyValue(ClientPropertyAnnotation property, object propertyValue, string serverTypeName, HashSet<object> visitedComplexTypeObjects, out ODataValue odataValue)
        {
            if (property.IsKnownType)
            {
                odataValue = CreateODataPrimitivePropertyValue(property, propertyValue);
                return true;
            }

            if (property.IsEnumType)
            {
                string enumValue;
                if (propertyValue == null)
                {
                    enumValue = null;
                }
                else
                {
                    enumValue = ClientTypeUtil.GetEnumValuesString(propertyValue.ToString(), property.PropertyType);
                }

                string typeNameInMetadata = this.requestInfo.ResolveNameFromType(property.PropertyType);
                odataValue = new ODataEnumValue(enumValue, typeNameInMetadata);
                return true;
            }

            if (property.IsPrimitiveOrEnumOrComplexCollection)
            {
                odataValue = this.CreateODataCollectionPropertyValue(property, propertyValue, serverTypeName, visitedComplexTypeObjects);
                return true;
            }

            if (!property.IsEntityCollection && !ClientTypeUtil.TypeIsEntity(property.PropertyType, this.requestInfo.Model))
            {
                odataValue = this.CreateODataComplexPropertyValue(property, propertyValue, visitedComplexTypeObjects);
                return true;
            }

            odataValue = null;
            return false;
        }