/// <summary> /// Gets the the CLR value for a primitive property. /// </summary> /// <param name="structuredValue">The structured value.</param> /// <param name="propertyName">Name of the property.</param> /// <returns>The clr value of the property.</returns> internal static object GetPrimitivePropertyClrValue(this IEdmStructuredValue structuredValue, string propertyName) { Debug.Assert(structuredValue != null, "entityInstance != null"); IEdmStructuredTypeReference valueType = structuredValue.Type.AsStructured(); IEdmPropertyValue propertyValue = structuredValue.FindPropertyValue(propertyName); if (propertyValue == null) { throw new ODataException(ErrorStrings.EdmValueUtils_PropertyDoesntExist(valueType.FullName(), propertyName)); } if (propertyValue.Value.ValueKind == EdmValueKind.Null) { return(null); } IEdmPrimitiveValue primitiveValue = propertyValue.Value as IEdmPrimitiveValue; if (primitiveValue == null) { throw new ODataException(ErrorStrings.EdmValueUtils_NonPrimitiveValue(propertyValue.Name, valueType.FullName())); } return(primitiveValue.ToClrValue()); }
/// <summary> /// Convert a primitive value which didn't match any of the known values of the TypeCode enumeration. /// </summary> /// <param name="primitiveValue">The value to convert.</param> /// <param name="type">The expected primitive type or null.</param> /// <returns>The converted value.</returns> private static IEdmDelayedValue ConvertPrimitiveValueWithoutTypeCode(object primitiveValue, IEdmPrimitiveTypeReference type) { byte[] bytes = primitiveValue as byte[]; if (bytes != null) { IEdmBinaryTypeReference binaryType = (IEdmBinaryTypeReference)EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Binary); return(new EdmBinaryConstant(binaryType, bytes)); } if (primitiveValue is Date) { IEdmPrimitiveTypeReference dateType = EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Date); return(new EdmDateConstant(dateType, (Date)primitiveValue)); } if (primitiveValue is DateTimeOffset) { IEdmTemporalTypeReference dateTimeOffsetType = (IEdmTemporalTypeReference)EnsurePrimitiveType(type, EdmPrimitiveTypeKind.DateTimeOffset); return(new EdmDateTimeOffsetConstant(dateTimeOffsetType, (DateTimeOffset)primitiveValue)); } if (primitiveValue is Guid) { type = EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Guid); return(new EdmGuidConstant(type, (Guid)primitiveValue)); } if (primitiveValue is TimeOfDay) { IEdmTemporalTypeReference timeOfDayType = (IEdmTemporalTypeReference)EnsurePrimitiveType(type, EdmPrimitiveTypeKind.TimeOfDay); return(new EdmTimeOfDayConstant(timeOfDayType, (TimeOfDay)primitiveValue)); } if (primitiveValue is TimeSpan) { IEdmTemporalTypeReference timeType = (IEdmTemporalTypeReference)EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Duration); return(new EdmDurationConstant(timeType, (TimeSpan)primitiveValue)); } if (primitiveValue is ISpatial) { // TODO: [JsonLight] Add support for spatial values in ODataEdmStructuredValue throw new NotImplementedException(); } #if ASTORIA_CLIENT IEdmDelayedValue convertPrimitiveValueWithoutTypeCode; if (TryConvertClientSpecificPrimitiveValue(primitiveValue, type, out convertPrimitiveValueWithoutTypeCode)) { return(convertPrimitiveValueWithoutTypeCode); } #endif throw new ODataException(ErrorStrings.EdmValueUtils_UnsupportedPrimitiveType(primitiveValue.GetType().FullName)); }
/// <summary> /// Gets the clr value of the edm value based on its type. /// </summary> /// <param name="edmValue">The edm value.</param> /// <returns>The clr value</returns> internal static object ToClrValue(this IEdmPrimitiveValue edmValue) { #if !ASTORIA_CLIENT #endif Debug.Assert(edmValue != null, "edmValue != null"); EdmPrimitiveTypeKind primitiveKind = edmValue.Type.PrimitiveKind(); switch (edmValue.ValueKind) { case EdmValueKind.Binary: return(((IEdmBinaryValue)edmValue).Value); case EdmValueKind.Boolean: return(((IEdmBooleanValue)edmValue).Value); case EdmValueKind.DateTimeOffset: return(((IEdmDateTimeOffsetValue)edmValue).Value); case EdmValueKind.Decimal: return(((IEdmDecimalValue)edmValue).Value); case EdmValueKind.Guid: return(((IEdmGuidValue)edmValue).Value); case EdmValueKind.String: return(((IEdmStringValue)edmValue).Value); case EdmValueKind.Duration: return(((IEdmDurationValue)edmValue).Value); case EdmValueKind.Floating: return(ConvertFloatingValue((IEdmFloatingValue)edmValue, primitiveKind)); case EdmValueKind.Integer: return(ConvertIntegerValue((IEdmIntegerValue)edmValue, primitiveKind)); case EdmValueKind.Date: return(((IEdmDateValue)edmValue).Value); case EdmValueKind.TimeOfDay: return(((IEdmTimeOfDayValue)edmValue).Value); } throw new ODataException(ErrorStrings.EdmValueUtils_CannotConvertTypeToClrValue(edmValue.ValueKind)); }
/// <summary> /// Gets the raw CLR value for the given <see cref="IEdmPropertyValue"/>. /// </summary> /// <param name="property">The property to get the value for.</param> /// <param name="type">The type which declared the property.</param> /// <returns>The raw CLR value of the property.</returns> private static object GetPropertyValue(IEdmPropertyValue property, IEdmTypeReference type) { Debug.Assert(property != null, "property != null"); IEdmValue propertyValue = property.Value; // DEVNOTE: though this check is not strictly necessary, and would be caught by later checks, // it seems worthwhile to fail fast if we can. if (propertyValue.ValueKind == EdmValueKind.Null) { throw Error.InvalidOperation(ErrorStrings.Context_NullKeysAreNotSupported(property.Name)); } var primitiveValue = propertyValue as IEdmPrimitiveValue; if (primitiveValue == null) { throw Error.InvalidOperation(ErrorStrings.ClientType_KeysMustBeSimpleTypes(property.Name, type.FullName(), propertyValue.Type.FullName())); } // DEVNOTE: This can return null, and will be handled later. The reason for this is that the client // and server have different ways of getting property values, but both will eventually hit the same // codepath and that is where the null is handled. return(primitiveValue.ToClrValue()); }
/// <summary> /// Ensures a primitive type reference for a given primitive type kind. /// </summary> /// <param name="type">The possibly null type reference.</param> /// <param name="primitiveKindFromValue">The primitive type kind to ensure.</param> /// <returns>An <see cref="IEdmPrimitiveTypeReference"/> instance created for the <paramref name="primitiveKindFromValue"/> /// if <paramref name="type"/> is null; if <paramref name="type"/> is not null, validates it and then returns it.</returns> private static IEdmPrimitiveTypeReference EnsurePrimitiveType(IEdmPrimitiveTypeReference type, EdmPrimitiveTypeKind primitiveKindFromValue) { if (type == null) { type = EdmCoreModel.Instance.GetPrimitive(primitiveKindFromValue, /*isNullable*/ true); } else { EdmPrimitiveTypeKind primitiveKindFromType = type.PrimitiveDefinition().PrimitiveKind; if (primitiveKindFromType != primitiveKindFromValue) { string typeName = type.FullName(); if (typeName == null) { throw new ODataException(ErrorStrings.EdmValueUtils_IncorrectPrimitiveTypeKindNoTypeName(primitiveKindFromType.ToString(), primitiveKindFromValue.ToString())); } throw new ODataException(ErrorStrings.EdmValueUtils_IncorrectPrimitiveTypeKind(typeName, primitiveKindFromValue.ToString(), primitiveKindFromType.ToString())); } } return(type); }