예제 #1
0
        internal static void AddTypeNameAnnotationAsNeeded(ODataEnumValue enumValue, IEdmEnumTypeReference enumType, 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(enumValue != null);

            // 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(metadataLevel))
                {
                    typeName = null;
                }
                else
                {
                    typeName = enumType.FullName();
                }

                enumValue.TypeAnnotation = new ODataTypeAnnotation(typeName);
            }
        }
예제 #2
0
        /// <summary>
        /// Creates an <see cref="ODataEnumValue"/> for the object represented by <paramref name="graph"/>.
        /// </summary>
        /// <param name="graph">The enum value.</param>
        /// <param name="enumType">The EDM enum type of the value.</param>
        /// <param name="writeContext">The serializer write context.</param>
        /// <returns>The created <see cref="ODataEnumValue"/>.</returns>
        public virtual ODataEnumValue CreateODataEnumValue(object graph, IEdmEnumTypeReference enumType,
                                                           ODataSerializerContext writeContext)
        {
            if (graph == null)
            {
                return(null);
            }

            string value = null;

            if (graph.GetType().IsEnum)
            {
                value = graph.ToString();
            }
            else
            {
                if (graph.GetType() == typeof(EdmEnumObject))
                {
                    value = ((EdmEnumObject)graph).Value;
                }
            }

            ODataEnumValue enumValue = new ODataEnumValue(value, enumType.FullName());

            ODataMetadataLevel metadataLevel = writeContext != null
                ? writeContext.MetadataLevel
                : ODataMetadataLevel.MinimalMetadata;

            AddTypeNameAnnotationAsNeeded(enumValue, enumType, metadataLevel);

            return(enumValue);
        }
예제 #3
0
        internal static bool TryBindIdentifier(string identifier, IEdmEnumTypeReference typeReference, IEdmModel modelWhenNoTypeReference, out QueryNode boundEnum)
        {
            boundEnum = null;
            string text = identifier;

            // parse the string, e.g., NS.Color'Green'
            // get type information, and also convert Green into an ODataEnumValue

            // find the first ', before that, it is namespace.type
            int indexOfSingleQuote = text.IndexOf('\'');

            if (indexOfSingleQuote < 0)
            {
                return(false);
            }

            string namespaceAndType = text.Substring(0, indexOfSingleQuote);

            Debug.Assert((typeReference == null) || (modelWhenNoTypeReference == null), "((typeReference == null) || (modelWhenNoTypeReference == null)");

            // validate typeReference but allow type name not found in model for delayed throwing.
            if ((typeReference != null) && !string.Equals(namespaceAndType, typeReference.FullName()))
            {
                return(false);
            }

            // get the type
            IEdmEnumType enumType = typeReference != null
                ?
                                    (IEdmEnumType)typeReference.Definition
                :
                                    UriEdmHelpers.FindEnumTypeFromModel(modelWhenNoTypeReference, namespaceAndType);

            if (enumType == null)
            {
                return(false);
            }

            // now, find out the value
            UriParserHelper.TryRemovePrefix(namespaceAndType, ref text);
            UriParserHelper.TryRemoveQuotes(ref text);

            // parse string or int value to edm enum value
            string         enumValueString = text;
            ODataEnumValue enumValue;

            if (!TryParseEnum(enumType, enumValueString, out enumValue))
            {
                return(false);
            }

            // create an enum node, enclosing an odata enum value
            IEdmEnumTypeReference enumTypeReference = typeReference ?? new EdmEnumTypeReference(enumType, false);

            boundEnum = new ConstantNode(enumValue, identifier, enumTypeReference);

            return(true);
        }
예제 #4
0
        /// <summary>
        /// Reads a string value of an XML element and gets TypeName from model's EdmEnumTypeReference.
        /// </summary>
        /// <param name="reader">The XML reader to read the value from.</param>
        /// <param name="enumTypeReference">The enum rype reference.</param>
        /// <returns>An ODataEnumValue</returns>
        internal static ODataEnumValue ReadEnumValue(XmlReader reader, IEdmEnumTypeReference enumTypeReference)
        {
            Debug.Assert(reader != null, "reader != null");

            // skip the validation on value or type name.
            string stringValue = reader.ReadElementContentValue();
            string typeName = (enumTypeReference != null) ? enumTypeReference.FullName() : null;
            return new ODataEnumValue(stringValue, typeName);
        }
예제 #5
0
        /// <summary>
        /// Reads a string value of an XML element and gets TypeName from model's EdmEnumTypeReference.
        /// </summary>
        /// <param name="reader">The XML reader to read the value from.</param>
        /// <param name="enumTypeReference">The enum rype reference.</param>
        /// <returns>An ODataEnumValue</returns>
        internal static ODataEnumValue ReadEnumValue(XmlReader reader, IEdmEnumTypeReference enumTypeReference)
        {
            Debug.Assert(reader != null, "reader != null");

            // skip the validation on value or type name.
            string stringValue = reader.ReadElementContentValue();
            string typeName    = (enumTypeReference != null) ? enumTypeReference.FullName() : null;

            return(new ODataEnumValue(stringValue, typeName));
        }
예제 #6
0
        internal static bool TryBindIdentifier(string identifier, IEdmEnumTypeReference typeReference, IEdmModel modelWhenNoTypeReference, out QueryNode boundEnum)
        {
            boundEnum = null;
            string text = identifier;

            // parse the string, e.g., NS.Color'Green'
            // get type information, and also convert Green into an ODataEnumValue

            // find the first ', before that, it is namespace.type
            int indexOfSingleQuote = text.IndexOf('\'');
            if (indexOfSingleQuote < 0)
            {
                return false;
            }

            string namespaceAndType = text.Substring(0, indexOfSingleQuote);
            Debug.Assert((typeReference == null) || (modelWhenNoTypeReference == null), "((typeReference == null) || (modelWhenNoTypeReference == null)");

            // validate typeReference but allow type name not found in model for delayed throwing.
            if ((typeReference != null) && !string.Equals(namespaceAndType, typeReference.FullName()))
            {
                return false;
            }

            // get the type
            IEdmEnumType enumType = typeReference != null
                ?
               (IEdmEnumType)typeReference.Definition
                :
                UriEdmHelpers.FindEnumTypeFromModel(modelWhenNoTypeReference, namespaceAndType);
            if (enumType == null)
            {
                return false;
            }

            // now, find out the value
            UriPrimitiveTypeParser.TryRemovePrefix(namespaceAndType, ref text);
            UriPrimitiveTypeParser.TryRemoveQuotes(ref text);

            // parse string or int value to edm enum value
            string enumValueString = text;
            ODataEnumValue enumValue;

            if (!TryParseEnum(enumType, enumValueString, out enumValue))
            {
                return false;
            }

            // create an enum node, enclosing an odata enum value
            IEdmEnumTypeReference enumTypeReference = typeReference ?? new EdmEnumTypeReference(enumType, false);
            boundEnum = new ConstantNode(enumValue, identifier, enumTypeReference);

            return true;
        }
예제 #7
0
        /// <summary>
        /// Creates an <see cref="ODataEnumValue"/> for the object represented by <paramref name="graph"/>.
        /// </summary>
        /// <param name="graph">The enum value.</param>
        /// <param name="enumType">The EDM enum type of the value.</param>
        /// <param name="writeContext">The serializer write context.</param>
        /// <returns>The created <see cref="ODataEnumValue"/>.</returns>
        public virtual ODataEnumValue CreateODataEnumValue(object graph, IEdmEnumTypeReference enumType,
                                                           ODataSerializerContext writeContext)
        {
            if (graph == null)
            {
                return(null);
            }

            string value = null;

            if (TypeHelper.IsEnum(graph.GetType()))
            {
                value = graph.ToString();
            }
            else
            {
                if (graph.GetType() == typeof(EdmEnumObject))
                {
                    value = ((EdmEnumObject)graph).Value;
                }
            }

            // Enum member supports model alias case. So, try to use the Edm member name to create Enum value.
            var memberMapAnnotation = writeContext.Model.GetClrEnumMemberAnnotation(enumType.EnumDefinition());

            if (memberMapAnnotation != null)
            {
                var edmEnumMember = memberMapAnnotation.GetEdmEnumMember((Enum)graph);
                if (edmEnumMember != null)
                {
                    value = edmEnumMember.Name;
                }
            }

            ODataEnumValue enumValue = new ODataEnumValue(value, enumType.FullName());

            ODataMetadataLevel metadataLevel = writeContext != null
                ? writeContext.MetadataLevel
                : ODataMetadataLevel.MinimalMetadata;

            AddTypeNameAnnotationAsNeeded(enumValue, enumType, metadataLevel);

            return(enumValue);
        }
        /// <summary>
        /// Creates an <see cref="ODataEnumValue"/> for the object represented by <paramref name="graph"/>.
        /// </summary>
        /// <param name="graph">The enum value.</param>
        /// <param name="enumType">The EDM enum type of the value.</param>
        /// <param name="writeContext">The serializer write context.</param>
        /// <returns>The created <see cref="ODataEnumValue"/>.</returns>
        public virtual ODataEnumValue CreateODataEnumValue(object graph, IEdmEnumTypeReference enumType,
            ODataSerializerContext writeContext)
        {
            if (graph == null)
            {
                return null;
            }

            string value = null;
            if (graph.GetType().IsEnum)
            {
                value = graph.ToString();
            }

            ODataEnumValue enumValue = new ODataEnumValue(value, enumType.FullName());

            ODataMetadataLevel metadataLevel = writeContext != null
                ? writeContext.MetadataLevel
                : ODataMetadataLevel.Default;
            AddTypeNameAnnotationAsNeeded(enumValue, enumType, metadataLevel);

            return enumValue;
        }
예제 #9
0
        internal static void AddTypeNameAnnotationAsNeeded(ODataEnumValue enumValue, IEdmEnumTypeReference enumType, 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(enumValue != null);

            // 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(metadataLevel))
                {
                    typeName = null;
                }
                else
                {
                    typeName = enumType.FullName();
                }

                enumValue.SetAnnotation(new SerializationTypeNameAnnotation
                {
                    TypeName = typeName
                });
            }
        }
        /// <summary>
        /// Reads a primitive string as enum value.
        /// </summary>
        /// <param name="insideJsonObjectValue">true if the reader is positioned on the first property of the value which is a JSON Object 
        ///     (or the second property if the first one was odata.type).</param>
        /// <param name="expectedValueTypeReference">The expected type reference of the value, or null if none is available.</param>
        /// <param name="validateNullValue">true to validate null values; otherwise false.</param>
        /// <param name="propertyName">The name of the property whose value is being read, if applicable (used for error reporting).</param>
        /// <returns>The Enum value from the primitive string.</returns>
        private object ReadEnumValue(bool insideJsonObjectValue, IEdmEnumTypeReference expectedValueTypeReference, bool validateNullValue, string propertyName)
        {
            if (insideJsonObjectValue)
            {
                // We manually throw JSON exception here to get a nicer error message (we expect primitive value and got object).
                // Otherwise the ReadPrimitiveValue would fail with something like "expected primitive value but found property/end object" which is rather confusing.
                throw new ODataException(ODataErrorStrings.JsonReaderExtensions_UnexpectedNodeDetectedWithPropertyName(JsonNodeType.PrimitiveValue, JsonNodeType.StartObject, propertyName));
            }

            string enumStr = this.JsonReader.ReadStringValue();
            return new ODataEnumValue(enumStr, expectedValueTypeReference.FullName());
        }
예제 #11
0
        /// <summary>
        /// Creates an <see cref="ODataEnumValue"/> for the object represented by <paramref name="graph"/>.
        /// </summary>
        /// <param name="graph">The enum value.</param>
        /// <param name="enumType">The EDM enum type of the value.</param>
        /// <param name="writeContext">The serializer write context.</param>
        /// <returns>The created <see cref="ODataEnumValue"/>.</returns>
        public virtual Task<ODataEnumValue> CreateODataEnumValueAsync(object graph, IEdmEnumTypeReference enumType,
            ODataSerializerContext writeContext)
        {
            if (graph == null)
            {
                return null;
            }

            string value = null;
            if (graph.GetType().GetTypeInfo().IsEnum)
            {
                value = graph.ToString();
            }
            else
            {
                if (graph.GetType() == typeof(EdmEnumObject))
                {
                    value = ((EdmEnumObject)graph).Value;
                }
            }

            ODataEnumValue enumValue = new ODataEnumValue(value, enumType.FullName());

            ODataMetadataLevel metadataLevel = writeContext != null
                ? writeContext.MetadataLevel
                : ODataMetadataLevel.MinimalMetadata;
            AddTypeNameAnnotationAsNeeded(enumValue, enumType, metadataLevel);

            return Task.FromResult(enumValue);
        }