/// <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)); }
private static IEdmType ResolveTypeName(IEdmModel model, IEdmType expectedType, string typeName, Func <IEdmType, string, IEdmType> customTypeResolver, ODataVersion version, out EdmTypeKind typeKind) { IEdmType collectionType = null; EdmTypeKind kind; string str = (version >= ODataVersion.V3) ? EdmLibraryExtensions.GetCollectionItemTypeName(typeName) : null; if (str == null) { if ((customTypeResolver != null) && model.IsUserModel()) { collectionType = customTypeResolver(expectedType, typeName); if (collectionType == null) { throw new ODataException(Microsoft.Data.OData.Strings.MetadataUtils_ResolveTypeName(typeName)); } } else { collectionType = model.FindType(typeName); } if (((version < ODataVersion.V3) && (collectionType != null)) && collectionType.IsSpatial()) { collectionType = null; } typeKind = (collectionType == null) ? EdmTypeKind.None : collectionType.TypeKind; return(collectionType); } typeKind = EdmTypeKind.Collection; IEdmType definition = null; if (((customTypeResolver != null) && (expectedType != null)) && (expectedType.TypeKind == EdmTypeKind.Collection)) { definition = ((IEdmCollectionType)expectedType).ElementType.Definition; } IEdmType itemType = ResolveTypeName(model, definition, str, customTypeResolver, version, out kind); if (itemType != null) { collectionType = EdmLibraryExtensions.GetCollectionType(itemType); } return(collectionType); }
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; }
internal static IEdmType ResolveTypeName( IEdmModel model, IEdmType expectedType, string typeName, Func <IEdmType, string, IEdmType> customTypeResolver, ODataVersion version, out EdmTypeKind typeKind) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(model != null, "model != null"); Debug.Assert(typeName != null, "typeName != null"); IEdmType resolvedType = null; // Collection types should only be recognized in V3 and higher. string itemTypeName = version >= ODataVersion.V3 ? EdmLibraryExtensions.GetCollectionItemTypeName(typeName) : null; if (itemTypeName == null) { // Note: we require the type resolver or the model to also resolve // primitive types. if (customTypeResolver != null && model.IsUserModel()) { resolvedType = customTypeResolver(expectedType, typeName); if (resolvedType == null) { // If a type resolver is specified it must never return null. throw new ODataException(Strings.MetadataUtils_ResolveTypeName(typeName)); } } else { resolvedType = model.FindType(typeName); } // Spatial types are only recognized in V3 and higher. if (version < ODataVersion.V3 && resolvedType != null && resolvedType.IsSpatial()) { resolvedType = null; } typeKind = resolvedType == null ? EdmTypeKind.None : resolvedType.TypeKind; } else { // Collection typeKind = EdmTypeKind.Collection; EdmTypeKind itemTypeKind; IEdmType expectedItemType = null; if (customTypeResolver != null && expectedType != null && expectedType.TypeKind == EdmTypeKind.Collection) { expectedItemType = ((IEdmCollectionType)expectedType).ElementType.Definition; } IEdmType itemType = ResolveTypeName(model, expectedItemType, itemTypeName, customTypeResolver, version, out itemTypeKind); if (itemType != null) { resolvedType = EdmLibraryExtensions.GetCollectionType(itemType); } } return(resolvedType); }