/// <summary> /// Verifies that the given <paramref name="primitiveValue"/> is or can be coerced to <paramref name="expectedTypeReference"/>, and coerces it if necessary. /// </summary> /// <param name="primitiveValue">An EDM primitive value to verify.</param> /// <param name="model">Model to verify against.</param> /// <param name="expectedTypeReference">Expected type reference.</param> /// <param name="version">The version to use for reading.</param> /// <returns>Coerced version of the <paramref name="primitiveValue"/>.</returns> internal static object VerifyAndCoerceUriPrimitiveLiteral(object primitiveValue, IEdmModel model, IEdmTypeReference expectedTypeReference, ODataVersion version) { DebugUtils.CheckNoExternalCallers(); ExceptionUtils.CheckArgumentNotNull(primitiveValue, "primitiveValue"); ExceptionUtils.CheckArgumentNotNull(model, "model"); ExceptionUtils.CheckArgumentNotNull(expectedTypeReference, "expectedTypeReference"); // First deal with null literal ODataUriNullValue nullValue = primitiveValue as ODataUriNullValue; if (nullValue != null) { if (!expectedTypeReference.IsNullable) { throw new ODataException(o.Strings.ODataUriUtils_ConvertFromUriLiteralNullOnNonNullableType(expectedTypeReference.ODataFullName())); } IEdmType actualResolvedType = ValidationUtils.ValidateValueTypeName(model, nullValue.TypeName, expectedTypeReference.Definition.TypeKind); Debug.Assert(actualResolvedType != null, "This is a primitive-only codepath so actualResolvedType != null."); if (actualResolvedType.IsSpatial()) { ODataVersionChecker.CheckSpatialValue(version); } if (TypePromotionUtils.CanConvertTo(actualResolvedType.ToTypeReference(), expectedTypeReference)) { nullValue.TypeName = expectedTypeReference.ODataFullName(); return(nullValue); } throw new ODataException(o.Strings.ODataUriUtils_ConvertFromUriLiteralNullTypeVerificationFailure(expectedTypeReference.ODataFullName(), nullValue.TypeName)); } // Only other positive case is a numeric primitive that needs to be coerced IEdmPrimitiveTypeReference expectedPrimitiveTypeReference = expectedTypeReference.AsPrimitiveOrNull(); if (expectedPrimitiveTypeReference == null) { throw new ODataException(o.Strings.ODataUriUtils_ConvertFromUriLiteralTypeVerificationFailure(expectedTypeReference.ODataFullName(), primitiveValue)); } object coercedResult = CoerceNumericType(primitiveValue, expectedPrimitiveTypeReference.PrimitiveDefinition()); if (coercedResult != null) { return(coercedResult); } Type actualType = primitiveValue.GetType(); Type targetType = TypeUtils.GetNonNullableType(EdmLibraryExtensions.GetPrimitiveClrType(expectedPrimitiveTypeReference)); // If target type is assignable from actual type, we're OK if (targetType.IsAssignableFrom(actualType)) { return(primitiveValue); } throw new ODataException(o.Strings.ODataUriUtils_ConvertFromUriLiteralTypeVerificationFailure(expectedPrimitiveTypeReference.ODataFullName(), primitiveValue)); }
/// <summary> /// If the source node is not of the specified type, then we check if type promotion is possible and inject a convert node. /// If the source node is the same type as the target type (or if the target type is null), we just return the source node as is. /// </summary> /// <param name="source">The source node to apply the convertion to.</param> /// <param name="targetTypeReference">The target primitive type. May be null - this method will do nothing in that case.</param> /// <returns>The converted query node, or the original source node unchanged.</returns> internal static SingleValueNode ConvertToTypeIfNeeded(SingleValueNode source, IEdmTypeReference targetTypeReference) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(source != null, "source != null"); if (targetTypeReference == null) { return(source); } if (source.TypeReference != null) { if (source.TypeReference.IsEquivalentTo(targetTypeReference)) { return(source); } if (!TypePromotionUtils.CanConvertTo(source.TypeReference, targetTypeReference)) { throw new ODataException(ODataErrorStrings.MetadataBinder_CannotConvertToType(source.TypeReference.ODataFullName(), targetTypeReference.ODataFullName())); } } // If the source doesn't have a type (possibly an open property), then it's possible to convert it // cause we don't know for sure. return(new ConvertNode(source, targetTypeReference)); }
internal static object VerifyAndCoerceUriPrimitiveLiteral(object primitiveValue, IEdmModel model, IEdmTypeReference expectedTypeReference, ODataVersion version) { ExceptionUtils.CheckArgumentNotNull<object>(primitiveValue, "primitiveValue"); ExceptionUtils.CheckArgumentNotNull<IEdmModel>(model, "model"); ExceptionUtils.CheckArgumentNotNull<IEdmTypeReference>(expectedTypeReference, "expectedTypeReference"); ODataUriNullValue value2 = primitiveValue as ODataUriNullValue; if (value2 != null) { if (!expectedTypeReference.IsNullable) { throw new ODataException(Microsoft.Data.OData.Strings.ODataUriUtils_ConvertFromUriLiteralNullOnNonNullableType(expectedTypeReference.ODataFullName())); } IEdmType type = ValidationUtils.ValidateValueTypeName(model, value2.TypeName, expectedTypeReference.Definition.TypeKind); if (type.IsSpatial()) { ODataVersionChecker.CheckSpatialValue(version); } if (!TypePromotionUtils.CanConvertTo(type.ToTypeReference(), expectedTypeReference)) { throw new ODataException(Microsoft.Data.OData.Strings.ODataUriUtils_ConvertFromUriLiteralNullTypeVerificationFailure(expectedTypeReference.ODataFullName(), value2.TypeName)); } value2.TypeName = expectedTypeReference.ODataFullName(); return value2; } IEdmPrimitiveTypeReference reference = expectedTypeReference.AsPrimitiveOrNull(); if (reference == null) { throw new ODataException(Microsoft.Data.OData.Strings.ODataUriUtils_ConvertFromUriLiteralTypeVerificationFailure(expectedTypeReference.ODataFullName(), primitiveValue)); } object obj2 = CoerceNumericType(primitiveValue, reference.PrimitiveDefinition()); if (obj2 != null) { return obj2; } Type c = primitiveValue.GetType(); if (!TypeUtils.GetNonNullableType(EdmLibraryExtensions.GetPrimitiveClrType(reference)).IsAssignableFrom(c)) { throw new ODataException(Microsoft.Data.OData.Strings.ODataUriUtils_ConvertFromUriLiteralTypeVerificationFailure(reference.ODataFullName(), primitiveValue)); } return primitiveValue; }