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); } }
/// <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); }
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); }
/// <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); }
/// <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)); }
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; }
/// <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; }
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()); }
/// <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); }