Пример #1
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);
        }
Пример #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 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);
            }
        }
Пример #4
0
            internal static object ConvertTo(ODataParameterValue parameterValue, HttpActionContext actionContext, ModelBindingContext bindingContext)
            {
                Contract.Assert(parameterValue != null && parameterValue.EdmType != null);

                object oDataValue = parameterValue.Value;

                if (oDataValue == null || oDataValue is ODataNullValue)
                {
                    return(null);
                }

                IEdmTypeReference        edmTypeReference = parameterValue.EdmType;
                ODataDeserializerContext readContext      = BuildDeserializerContext(actionContext, bindingContext, edmTypeReference);

                // complex value
                ODataComplexValue complexValue = oDataValue as ODataComplexValue;

                if (complexValue != null)
                {
                    IEdmComplexTypeReference edmComplexType = edmTypeReference.AsComplex();
                    Contract.Assert(edmComplexType != null);

                    ODataComplexTypeDeserializer deserializer =
                        (ODataComplexTypeDeserializer)DeserializerProvider.GetEdmTypeDeserializer(edmComplexType);

                    return(deserializer.ReadInline(complexValue, edmComplexType, readContext));
                }

                // collection of primitive, enum, complex
                ODataCollectionValue collectionValue = oDataValue as ODataCollectionValue;

                if (collectionValue != null)
                {
                    return(ConvertCollection(collectionValue, edmTypeReference, bindingContext, readContext));
                }

                // enum value
                ODataEnumValue enumValue = oDataValue as ODataEnumValue;

                if (enumValue != null)
                {
                    IEdmEnumTypeReference edmEnumType = edmTypeReference.AsEnum();
                    Contract.Assert(edmEnumType != null);

                    ODataEnumDeserializer deserializer =
                        (ODataEnumDeserializer)DeserializerProvider.GetEdmTypeDeserializer(edmEnumType);

                    return(deserializer.ReadInline(enumValue, edmEnumType, readContext));
                }

                // primitive value
                if (edmTypeReference.IsPrimitive())
                {
                    return(EdmPrimitiveHelpers.ConvertPrimitiveValue(oDataValue, bindingContext.ModelType));
                }

                // Entity, Feed, Entity Reference or collection of entity reference
                return(ConvertFeedOrEntry(oDataValue, edmTypeReference, readContext));
            }
Пример #5
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);
        }
Пример #6
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.ODataFullName() : null;
            return new ODataEnumValue(stringValue, typeName);
        }
Пример #7
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));
        }
Пример #8
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.ODataFullName()))
            {
                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;
        }
        /// <summary>
        /// Read an enumeration value from the reader.
        /// </summary>
        /// <param name="actualValueTypeReference">The thpe of the value to read.</param>
        /// <returns>An ODataEnumValue with the value read from the payload.</returns>
        private ODataEnumValue ReadEnumValue(IEdmEnumTypeReference actualValueTypeReference)
        {
            Debug.Assert(actualValueTypeReference != null, "actualValueTypeReference != null");
            Debug.Assert(actualValueTypeReference.TypeKind() == EdmTypeKind.Enum, "Only Enum values can be read by this method.");
            this.AssertXmlCondition(XmlNodeType.Element, XmlNodeType.Attribute);

            ODataEnumValue result = AtomValueUtils.ReadEnumValue(this.XmlReader, actualValueTypeReference);

            this.AssertXmlCondition(true, XmlNodeType.EndElement);
            Debug.Assert(result != null, "The method should never return null since it doesn't handle null values.");
            return(result);
        }
        public override ODataEnumValue CreateODataEnumValue(object graph, IEdmEnumTypeReference enumType, ODataSerializerContext writeContext)
        {
            ODataEnumValue result = base.CreateODataEnumValue(graph, enumType, writeContext);

            if (!string.IsNullOrEmpty(result?.Value) && !string.IsNullOrEmpty(result.TypeName))
            {
                // EnumKey >> "Namespace.EnumType'EnumKey'"
                result = new ODataEnumValue($"{result.TypeName}'{result.Value}'");
            }

            return(result);
        }
Пример #11
0
        /// <inheritdoc />
        public override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                return(null);
            }

            if (readContext == null)
            {
                throw Error.ArgumentNull(nameof(readContext));
            }

            ODataProperty property = item as ODataProperty;

            if (property != null)
            {
                item = property.Value;
            }

            IEdmEnumTypeReference enumTypeReference = edmType.AsEnum();
            ODataEnumValue        enumValue         = item as ODataEnumValue;

            if (readContext.IsNoClrType)
            {
                Contract.Assert(edmType.TypeKind() == EdmTypeKind.Enum);
                return(new EdmEnumObject(enumTypeReference, enumValue.Value));
            }

            IEdmEnumType enumType = enumTypeReference.EnumDefinition();

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

            if (memberMapAnnotation != null)
            {
                if (enumValue != null)
                {
                    IEdmEnumMember enumMember = enumType.Members.FirstOrDefault(m => m.Name == enumValue.Value);
                    if (enumMember != null)
                    {
                        var clrMember = memberMapAnnotation.GetClrEnumMember(enumMember);
                        if (clrMember != null)
                        {
                            return(clrMember);
                        }
                    }
                }
            }

            Type clrType = readContext.Model.GetClrType(edmType);

            return(EnumDeserializationHelpers.ConvertEnumValue(item, clrType));
        }
Пример #12
0
        /// <summary>
        /// Convert enum int value to string
        /// </summary>
        /// <param name="type">edm enum type reference</param>
        /// <param name="value">input int value</param>
        /// <returns>string literal of the enum value</returns>
        public static string ToStringLiteral(this IEdmEnumTypeReference type, Int64 value)
        {
            if (type != null)
            {
                // parse the value to string literal
                IEdmEnumType enumType = type.Definition as IEdmEnumType;
                if (enumType != null)
                {
                    return(enumType.IsFlags ? enumType.ToStringWithFlags(value) : enumType.ToStringNoFlags(value));
                }
            }

            return(value.ToString(CultureInfo.InvariantCulture));
        }
Пример #13
0
        public override ODataEnumValue CreateODataEnumValue(object graph, IEdmEnumTypeReference enumType, ODataSerializerContext writeContext)
        {
            ODataEnumValue result = base.CreateODataEnumValue(graph, enumType, writeContext);

            if (writeContext.Request.Headers.TryGetValues("Bit-Client-Type", out IEnumerable <string> values) && values.Any(v => string.Equals(v, "TS-Client", System.StringComparison.InvariantCultureIgnoreCase)))
            {
                if (!string.IsNullOrEmpty(result?.Value) && !string.IsNullOrEmpty(result.TypeName))
                {
                    // EnumKey >> "Namespace.EnumType'EnumKey'"
                    result = new ODataEnumValue($"{result.TypeName}'{result.Value}'");
                }
            }

            return(result);
        }
        private static OpenApiSchema CreateEnumTypeSchema(this ODataContext context, IEdmEnumTypeReference typeReference)
        {
            Debug.Assert(context != null);
            Debug.Assert(typeReference != null);

            OpenApiSchema schema = new OpenApiSchema();

            schema.Nullable  = typeReference.IsNullable;
            schema.AnyOf     = null;
            schema.Reference = new OpenApiReference
            {
                Type = ReferenceType.Schema,
                Id   = typeReference.Definition.FullTypeName()
            };

            return(schema);
        }
        public override ODataEnumValue CreateODataEnumValue(object graph, IEdmEnumTypeReference enumType, ODataSerializerContext writeContext)
        {
            ODataEnumValue result = base.CreateODataEnumValue(graph, enumType, writeContext);

            string clientType = writeContext.Request.GetOwinContext().GetDependencyResolver().Resolve <IRequestInformationProvider>().BitClientType;

            if (string.Equals(clientType, "TS-Client", System.StringComparison.InvariantCultureIgnoreCase))
            {
                if (!string.IsNullOrEmpty(result?.Value) && !string.IsNullOrEmpty(result.TypeName))
                {
                    // EnumKey >> "Namespace.EnumType'EnumKey'"
                    result = new ODataEnumValue($"{result.TypeName}'{result.Value}'");
                }
            }

            return(result);
        }
Пример #16
0
        /// <summary>
        /// Convert an OData value into a CLR object.
        /// </summary>
        /// <param name="graph">The given object.</param>
        /// <param name="edmTypeReference">The EDM type of the given object.</param>
        /// <param name="clrType">The CLR type of the given object.</param>
        /// <param name="parameterName">The parameter name of the given object.</param>
        /// <param name="readContext">The <see cref="ODataDeserializerContext"/> use to convert.</param>
        /// <param name="requestContainer">The dependency injection container for the request.</param>
        /// <returns>The converted object.</returns>
        public static object Convert(object graph, IEdmTypeReference edmTypeReference,
                                     Type clrType, string parameterName, ODataDeserializerContext readContext,
                                     IServiceProvider requestContainer)
        {
            if (graph == null || graph is ODataNullValue)
            {
                return(null);
            }

            // collection of primitive, enum
            ODataCollectionValue collectionValue = graph as ODataCollectionValue;

            if (collectionValue != null)
            {
                return(ConvertCollection(collectionValue, edmTypeReference, clrType, parameterName, readContext,
                                         requestContainer));
            }

            // enum value
            ODataEnumValue enumValue = graph as ODataEnumValue;

            if (enumValue != null)
            {
                IEdmEnumTypeReference edmEnumType = edmTypeReference.AsEnum();
                Contract.Assert(edmEnumType != null);

                ODataDeserializerProvider deserializerProvider =
                    requestContainer.GetRequiredService <ODataDeserializerProvider>();

                ODataEnumDeserializer deserializer =
                    (ODataEnumDeserializer)deserializerProvider.GetEdmTypeDeserializer(edmEnumType);

                return(deserializer.ReadInline(enumValue, edmEnumType, readContext));
            }

            // primitive value
            if (edmTypeReference.IsPrimitive())
            {
                ConstantNode node = graph as ConstantNode;
                return(EdmPrimitiveHelper.ConvertPrimitiveValue(node != null ? node.Value : graph, clrType, readContext.TimeZone));
            }

            // Resource, ResourceSet, Entity Reference or collection of entity reference
            return(ConvertResourceOrResourceSet(graph, edmTypeReference, readContext));
        }
Пример #17
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);
        }
        private static OpenApiSchema CreateEnumTypeSchema(this ODataContext context, IEdmEnumTypeReference typeReference)
        {
            Debug.Assert(context != null);
            Debug.Assert(typeReference != null);

            OpenApiSchema schema = new OpenApiSchema();

            schema.Reference = null;

            if (typeReference.IsNullable && context.Settings.OpenApiSpecVersion >= OpenApiSpecVersion.OpenApi3_0)
            {
                schema.AnyOf = new List <OpenApiSchema>
                {
                    new OpenApiSchema
                    {
                        UnresolvedReference = true,
                        Reference           = new OpenApiReference
                        {
                            Type = ReferenceType.Schema,
                            Id   = typeReference.Definition.FullTypeName()
                        }
                    },
                    new OpenApiSchema
                    {
                        Type     = "object",
                        Nullable = true
                    }
                };
            }
            else
            {
                schema.Type      = null;
                schema.AnyOf     = null;
                schema.Reference = new OpenApiReference
                {
                    Type = ReferenceType.Schema,
                    Id   = typeReference.Definition.FullTypeName()
                };
                schema.UnresolvedReference = true;
                schema.Nullable            = typeReference.IsNullable;
            }

            return(schema);
        }
Пример #19
0
        /// <summary>
        /// If this reference is of an enumeration type, this will return a valid enumeration type reference to the type definition. Otherwise, it will return a bad enumeration type reference.
        /// </summary>
        /// <param name="type">Reference to the calling object.</param>
        /// <returns>A valid enumeration type reference if the definition of the reference is of an enumeration type. Otherwise a bad enumeration type reference.</returns>
        public static IEdmEnumTypeReference AsEnum(this IEdmTypeReference type)
        {
            EdmUtil.CheckArgumentNull(type, "type");
            IEdmEnumTypeReference reference = type as IEdmEnumTypeReference;

            if (reference != null)
            {
                return(reference);
            }

            IEdmType typeDefinition = type.Definition;

            if (typeDefinition.TypeKind == EdmTypeKind.Enum)
            {
                return(new EdmEnumTypeReference((IEdmEnumType)typeDefinition, type.IsNullable));
            }

            string typeFullName = type.FullName();

            return(new EdmEnumTypeReference(
                       new BadEnumType(typeFullName, ConversionError(type.Location(), typeFullName, EdmConstants.Type_Enum)),
                       type.IsNullable));
        }
Пример #20
0
        public static IEdmEnumTypeReference AsEnum(this IEdmTypeReference type)
        {
            EdmUtil.CheckArgumentNull <IEdmTypeReference>(type, "type");
            IEdmEnumTypeReference edmEnumTypeReference = type as IEdmEnumTypeReference;

            if (edmEnumTypeReference == null)
            {
                IEdmType definition = type.Definition;
                if (definition.TypeKind != EdmTypeKind.Enum)
                {
                    string str = type.FullName();
                    return(new EdmEnumTypeReference(new BadEnumType(str, EdmTypeSemantics.ConversionError(type.Location(), str, "Enum")), type.IsNullable));
                }
                else
                {
                    return(new EdmEnumTypeReference((IEdmEnumType)definition, type.IsNullable));
                }
            }
            else
            {
                return(edmEnumTypeReference);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmEnumValue"/> class.
 /// </summary>
 /// <param name="type">A reference to the enumeration type that describes this value.</param>
 /// <param name="value">The underlying type value.</param>
 public EdmEnumValue(IEdmEnumTypeReference type, IEdmPrimitiveValue value)
     : base(type)
 {
     this.value = value;
 }
Пример #22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmEnumValue"/> class.
 /// </summary>
 /// <param name="type">A reference to the enumeration type that describes this value.</param>
 /// <param name="member">The enumeration type value.</param>
 public EdmEnumValue(IEdmEnumTypeReference type, IEdmEnumMember member)
     : this(type, member.Value)
 {
 }
Пример #23
0
        public void CsdlTypeReferenceToStringTest()
        {
            const string csdl =
                @"<?xml version=""1.0"" encoding=""utf-16""?>
<Schema Namespace=""AwesomeNamespace"" Alias=""Alias"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
  <EntityType Name=""AstonishingEntity"">
    <Key>
      <PropertyRef Name=""Id"" />
    </Key>
    <Property Name=""Id"" Type=""Int32"" Nullable=""false"" />
  </EntityType>
  <EntityType Name=""AweInspiringEntity"">
    <Key>
      <PropertyRef Name=""Id"" />
    </Key>
    <Property Name=""Id"" Type=""Int32"" Nullable=""false"" />
    <Property Name=""AstonishingID"" Type=""Int32"" />
  </EntityType>
  <ComplexType Name=""BreathtakingComplex"">
    <Property Name=""Par1"" Type=""Int32"" Nullable=""false"" />
    <Property Name=""Par2"" Type=""Int32"" Nullable=""false"" />
  </ComplexType>
  <Function Name=""Function1""><ReturnType Type=""Edm.Int32""/>
    <Parameter Name=""P1"" Type=""AwesomeNamespace.AstonishingEntity"" />
    <Parameter Name=""P2"" Type=""AwesomeNamespace.BreathtakingComplex"" />
    <Parameter Name=""P3"" Type=""AwesomeNamespace.ExaltedAssociation"" />
    <Parameter Name=""P4"" Type=""Edm.Int32"" />
    <Parameter Name=""P5"" Type=""Edm.String"" MaxLength=""128"" Unicode=""false"" />
    <Parameter Name=""P6"" Type=""Edm.Stream"" />
    <Parameter Name=""P7"" Type=""Edm.Binary"" MaxLength=""max""/>
    <Parameter Name=""P8"" Type=""Edm.DateTimeOffset"" Precision=""1"" />
    <Parameter Name=""P9"" Type=""Edm.Decimal"" Precision=""3"" Scale=""2""/>
    <Parameter Name=""P10"" Type=""Edm.Geography"" SRID=""1""  />
    <Parameter Name=""P11"" Type=""Ref(AwesomeNamespace.AstonishingEntity)"" />
    <Parameter Name=""P12"" Type=""Collection(Edm.Int32)"" />
    <Parameter Name=""P14"" Type=""AwesomeNamespace.FabulousEnum"" />
  </Function>
  <EnumType Name=""FabulousEnum"">
    <Member Name=""m1"" />
    <Member Name=""m2"" />
  </EnumType>
</Schema>";
            IEdmModel model;
            IEnumerable <EdmError> errors;
            bool parsed = CsdlReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(csdl)) }, out model, out errors);

            Assert.IsTrue(parsed, "parsed");
            Assert.IsTrue(errors.Count() == 0, "No errors");

            IEdmOperation operation = (IEdmOperation)(model.FindOperations("AwesomeNamespace.Function1")).First();

            IEdmEntityTypeReference          entity      = operation.FindParameter("P1").Type.AsEntity();
            IEdmComplexTypeReference         complex     = operation.FindParameter("P2").Type.AsComplex();
            IEdmTypeReference                association = operation.FindParameter("P3").Type;
            IEdmPrimitiveTypeReference       primitive   = operation.FindParameter("P4").Type.AsPrimitive();
            IEdmStringTypeReference          stringType  = operation.FindParameter("P5").Type.AsString();
            IEdmPrimitiveTypeReference       stream      = operation.FindParameter("P6").Type.AsPrimitive();
            IEdmBinaryTypeReference          binary      = operation.FindParameter("P7").Type.AsBinary();
            IEdmTemporalTypeReference        temporal    = operation.FindParameter("P8").Type.AsTemporal();
            IEdmDecimalTypeReference         decimalType = operation.FindParameter("P9").Type.AsDecimal();
            IEdmSpatialTypeReference         spatial     = operation.FindParameter("P10").Type.AsSpatial();
            IEdmEntityReferenceTypeReference entityRef   = operation.FindParameter("P11").Type.AsEntityReference();
            IEdmCollectionTypeReference      collection  = operation.FindParameter("P12").Type.AsCollection();
            IEdmEnumTypeReference            enumTypeRef = operation.FindParameter("P14").Type.AsEnum();
            IEdmTypeReference                type        = operation.FindParameter("P1").Type;

            Assert.IsFalse(association.IsBad(), "Associations cannot be types");
            Assert.IsTrue(association.Definition.IsBad(), "Associations cannot be types");
            Assert.AreEqual("[AwesomeNamespace.AstonishingEntity Nullable=True]", entity.ToString(), "To string correct");
            Assert.AreEqual("[AwesomeNamespace.BreathtakingComplex Nullable=True]", complex.ToString(), "To string correct");
            Assert.AreEqual("[Edm.Int32 Nullable=True]", primitive.ToString(), "To string correct");
            Assert.AreEqual("[Edm.String Nullable=True MaxLength=128 Unicode=False]", stringType.ToString(), "To string correct");
            Assert.AreEqual("[Edm.Stream Nullable=True]", stream.ToString(), "To string correct");
            Assert.AreEqual("[Edm.Binary Nullable=True MaxLength=max]", binary.ToString(), "To string correct");
            Assert.AreEqual("[Edm.DateTimeOffset Nullable=True Precision=1]", temporal.ToString(), "To string correct");
            Assert.AreEqual("[Edm.Decimal Nullable=True Precision=3 Scale=2]", decimalType.ToString(), "To string correct");
            Assert.AreEqual("[Edm.Geography Nullable=True SRID=1]", spatial.ToString(), "To string correct");
            Assert.AreEqual("[Collection([Edm.Int32 Nullable=True]) Nullable=True]", collection.ToString(), "To string correct");
            Assert.AreEqual("[EntityReference(AwesomeNamespace.AstonishingEntity) Nullable=True]", entityRef.ToString(), "To string correct");
            Assert.AreEqual("[AwesomeNamespace.FabulousEnum Nullable=True]", enumTypeRef.ToString(), "To string correct");
            Assert.AreEqual("[AwesomeNamespace.AstonishingEntity Nullable=True]", type.ToString(), "To string correct");
        }
        /// <summary>
        /// Reads the next parameter from the parameters payload.
        /// </summary>
        /// <param name="propertyAndAnnotationCollector">The duplicate property names checker used to read a parameter payload.</param>
        /// <returns>true if a parameter was read from the payload; otherwise false.</returns>
        /// <remarks>
        /// Pre-Condition:  Property or EndObject   the property node of the parameter to read or the end object node if there are not parameters
        /// Post-Condition: Property or EndObject   the node after the property value of a primitive, complex or null collection parameter
        ///                 Any                     the start of the value representing a non-null collection parameter (the collection reader will fail if this is not a StartArray node)
        /// </remarks>
        internal bool ReadNextParameter(PropertyAndAnnotationCollector propertyAndAnnotationCollector)
        {
            Debug.Assert(propertyAndAnnotationCollector != null, "propertyAndAnnotationCollector != null");
            this.AssertJsonCondition(JsonNodeType.Property, JsonNodeType.EndObject);

            bool parameterRead = false;

            if (this.JsonReader.NodeType == JsonNodeType.Property)
            {
                bool foundCustomInstanceAnnotation = false;
                this.ProcessProperty(
                    propertyAndAnnotationCollector,
                    propertyAnnotationValueReader,
                    (propertyParsingResult, parameterName) =>
                {
                    if (this.JsonReader.NodeType == JsonNodeType.Property)
                    {
                        // Read over property name
                        this.JsonReader.Read();
                    }

                    switch (propertyParsingResult)
                    {
                    case PropertyParsingResult.ODataInstanceAnnotation:
                        // OData instance annotations are not supported in parameter payloads.
                        throw new ODataException(ODataErrorStrings.ODataJsonLightPropertyAndValueDeserializer_UnexpectedAnnotationProperties(parameterName));

                    case PropertyParsingResult.CustomInstanceAnnotation:
                        this.JsonReader.SkipValue();
                        foundCustomInstanceAnnotation = true;
                        break;

                    case PropertyParsingResult.PropertyWithoutValue:
                        throw new ODataException(ODataErrorStrings.ODataJsonLightParameterDeserializer_PropertyAnnotationWithoutPropertyForParameters(parameterName));

                    case PropertyParsingResult.EndOfObject:
                        break;

                    case PropertyParsingResult.MetadataReferenceProperty:
                        throw new ODataException(ODataErrorStrings.ODataJsonLightPropertyAndValueDeserializer_UnexpectedMetadataReferenceProperty(parameterName));

                    case PropertyParsingResult.PropertyWithValue:
                        IEdmTypeReference parameterTypeReference = this.parameterReader.GetParameterTypeReference(parameterName);
                        Debug.Assert(parameterTypeReference != null, "parameterTypeReference != null");

                        ODataParameterReaderState state;
                        object parameterValue;
                        EdmTypeKind parameterTypeKind = parameterTypeReference.TypeKind();
                        switch (parameterTypeKind)
                        {
                        case EdmTypeKind.Primitive:
                            IEdmPrimitiveTypeReference primitiveTypeReference = parameterTypeReference.AsPrimitive();
                            if (primitiveTypeReference.PrimitiveKind() == EdmPrimitiveTypeKind.Stream)
                            {
                                throw new ODataException(ODataErrorStrings.ODataJsonLightParameterDeserializer_UnsupportedPrimitiveParameterType(parameterName, primitiveTypeReference.PrimitiveKind()));
                            }

                            parameterValue = this.ReadNonEntityValue(
                                /*payloadTypeName*/ null,
                                primitiveTypeReference,
                                /*propertyAndAnnotationCollector*/ null,
                                /*collectionValidator*/ null,
                                /*validateNullValue*/ true,
                                /*isTopLevelPropertyValue*/ false,
                                /*insideComplexValue*/ false,
                                parameterName);
                            state = ODataParameterReaderState.Value;
                            break;

                        case EdmTypeKind.Enum:
                            IEdmEnumTypeReference enumTypeReference = parameterTypeReference.AsEnum();
                            parameterValue = this.ReadNonEntityValue(
                                /*payloadTypeName*/ null,
                                enumTypeReference,
                                /*propertyAndAnnotationCollector*/ null,
                                /*collectionValidator*/ null,
                                /*validateNullValue*/ true,
                                /*isTopLevelPropertyValue*/ false,
                                /*insideComplexValue*/ false,
                                parameterName);
                            state = ODataParameterReaderState.Value;
                            break;

                        case EdmTypeKind.TypeDefinition:
                            IEdmTypeDefinitionReference typeDefinitionReference = parameterTypeReference.AsTypeDefinition();
                            parameterValue = this.ReadNonEntityValue(
                                /*payloadTypeName*/ null,
                                typeDefinitionReference,
                                /*propertyAndAnnotationCollector*/ null,
                                /*collectionValidator*/ null,
                                /*validateNullValue*/ true,
                                /*isTopLevelPropertyValue*/ false,
                                /*insideComplexValue*/ false,
                                parameterName);
                            state = ODataParameterReaderState.Value;
                            break;

                        case EdmTypeKind.Complex:
                        case EdmTypeKind.Entity:
                            parameterValue = null;
                            state          = ODataParameterReaderState.Resource;
                            break;

                        case EdmTypeKind.Collection:
                            parameterValue = null;
                            if (this.JsonReader.NodeType == JsonNodeType.PrimitiveValue)
                            {
                                // NOTE: we support null collections in parameter payloads but nowhere else.
                                parameterValue = this.JsonReader.ReadPrimitiveValue();
                                if (parameterValue != null)
                                {
                                    throw new ODataException(ODataErrorStrings.ODataJsonLightParameterDeserializer_NullCollectionExpected(JsonNodeType.PrimitiveValue, parameterValue));
                                }

                                state = ODataParameterReaderState.Value;
                            }
                            else if (((IEdmCollectionType)parameterTypeReference.Definition).ElementType.IsStructured())
                            {
                                state = ODataParameterReaderState.ResourceSet;
                            }
                            else
                            {
                                state = ODataParameterReaderState.Collection;
                            }

                            break;

                        default:

                            throw new ODataException(ODataErrorStrings.ODataJsonLightParameterDeserializer_UnsupportedParameterTypeKind(parameterName, parameterTypeReference.TypeKind()));
                        }

                        parameterRead = true;
                        this.parameterReader.EnterScope(state, parameterName, parameterValue);
                        Debug.Assert(
                            state == ODataParameterReaderState.Collection || state == ODataParameterReaderState.Resource || state == ODataParameterReaderState.ResourceSet || this.JsonReader.NodeType == JsonNodeType.Property || this.JsonReader.NodeType == JsonNodeType.EndObject,
                            "Expected any node for a collection; 'Property' or 'EndObject' if it is a primitive or complex value.");
                        break;

                    default:
                        throw new ODataException(ODataErrorStrings.General_InternalError(InternalErrorCodes.ODataJsonLightParameterDeserializer_ReadNextParameter));
                    }
                });

                if (foundCustomInstanceAnnotation)
                {
                    return(this.ReadNextParameter(propertyAndAnnotationCollector));
                }
            }

            if (!parameterRead && this.JsonReader.NodeType == JsonNodeType.EndObject)
            {
                this.JsonReader.ReadEndObject();
                this.ReadPayloadEnd(/*isReadingNestedPayload*/ false);

                // Pop the scope for the previous parameter if there is any
                if (this.parameterReader.State != ODataParameterReaderState.Start)
                {
                    this.parameterReader.PopScope(this.parameterReader.State);
                }

                // Pop the 'Start' scope and enter the 'Completed' scope
                this.parameterReader.PopScope(ODataParameterReaderState.Start);
                this.parameterReader.EnterScope(ODataParameterReaderState.Completed, /*parameterName*/ null, /*parameterValue*/ null);
                this.AssertJsonCondition(JsonNodeType.EndOfInput);
            }

            return(parameterRead);
        }
Пример #25
0
 public TestEdmEnumObject(IEdmEnumTypeReference edmType, string value)
     : base(edmType, value)
 {
 }
 protected override void ProcessEnumTypeReference(IEdmEnumTypeReference element)
 {
     this.CheckSchemaElementReference(element.EnumDefinition());
 }
Пример #27
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmEnumValue"/> class. 
 /// </summary>
 /// <param name="type">A reference to the enumeration type that describes this value.</param>
 /// <param name="value">The underlying type value.</param>
 public EdmEnumValue(IEdmEnumTypeReference type, IEdmPrimitiveValue value)
     : base(type)
 {
     this.value = value;
 }
Пример #28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmEnumObject"/> class.
 /// </summary>
 /// <param name="edmType">The <see cref="IEdmEnumTypeReference"/> of this object.</param>
 /// <param name="value">The value of the enumeration type.</param>
 public EdmEnumObject(IEdmEnumTypeReference edmType, string value)
     : this(edmType.EnumDefinition(), value, edmType.IsNullable)
 {
 }
 public ODataEnumSerializer(IEdmEnumTypeReference edmEnumType, ODataSerializerProvider serializerProvider)
     : base(edmEnumType, ODataPayloadKind.Property, serializerProvider)
 {
 }
Пример #30
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmEnumObject"/> class.
 /// </summary>
 /// <param name="edmType">The <see cref="IEdmEnumTypeReference"/> of this object.</param>
 /// <param name="value">The value of the enumeration type.</param>
 public EdmEnumObject(IEdmEnumTypeReference edmType, string value)
     : this(edmType.EnumDefinition(), value, edmType.IsNullable)
 {
 }
 protected override void ProcessEnumTypeReference(IEdmEnumTypeReference element)
 {
     this.CheckSchemaElementReference(element.EnumDefinition());
 }
Пример #32
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
                });
            }
        }
Пример #33
0
 protected virtual void ProcessEnumTypeReference(IEdmEnumTypeReference reference)
 {
     this.ProcessTypeReference(reference);
 }
Пример #34
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmEnumValue"/> class.
 /// </summary>
 /// <param name="type">A reference to the enumeration type that describes this value.</param>
 /// <param name="value">The underlying type value.</param>
 public EdmEnumValue(IEdmEnumTypeReference type, IEdmEnumMemberValue value)
     : base(type)
 {
     this.value = value;
 }
        /// <summary>
        /// Read an enumeration value from the reader.
        /// </summary>
        /// <param name="actualValueTypeReference">The thpe of the value to read.</param>
        /// <returns>An ODataEnumValue with the value read from the payload.</returns>
        private ODataEnumValue ReadEnumValue(IEdmEnumTypeReference actualValueTypeReference)
        {
            Debug.Assert(actualValueTypeReference != null, "actualValueTypeReference != null");
            Debug.Assert(actualValueTypeReference.TypeKind() == EdmTypeKind.Enum, "Only Enum values can be read by this method.");
            this.AssertXmlCondition(XmlNodeType.Element, XmlNodeType.Attribute);

            ODataEnumValue result = AtomValueUtils.ReadEnumValue(this.XmlReader, actualValueTypeReference);
            this.AssertXmlCondition(true, XmlNodeType.EndElement);
            Debug.Assert(result != null, "The method should never return null since it doesn't handle null values.");
            return result;
        }
        /// <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());
        }
Пример #37
0
 /// <summary>
 /// Try to bind an identifier to a EnumNode
 /// </summary>
 /// <param name="identifier">the identifier to bind</param>
 /// <param name="typeReference">the enum typeReference</param>
 /// <param name="modelWhenNoTypeReference">the current model when no enum typeReference.</param>
 /// <param name="boundEnum">an enum node .</param>
 /// <returns>true if we bound an enum for this token.</returns>
 internal static bool TryBindIdentifier(string identifier, IEdmEnumTypeReference typeReference, IEdmModel modelWhenNoTypeReference, out QueryNode boundEnum)
 {
     return(TryBindIdentifier(identifier, typeReference, modelWhenNoTypeReference, null, out boundEnum));
 }
Пример #38
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EdmEnumValue"/> class. 
 /// </summary>
 /// <param name="type">A reference to the enumeration type that describes this value.</param>
 /// <param name="member">The enumeration type value.</param>
 public EdmEnumValue(IEdmEnumTypeReference type, IEdmEnumMember member)
     : this(type, member.Value)
 {
 }
Пример #39
0
 public TestEdmEnumObject(IEdmEnumTypeReference edmType, string value)
     : base(edmType, value)
 {
 }