Beispiel #1
0
        /// <summary>
        /// Returns the primitive property value.
        /// </summary>
        /// <param name="propertyValue">Value of the property.</param>
        /// <param name="propertyType">Type of the property.</param>
        /// <returns>Returns the value of the primitive property.</returns>
        internal static object ConvertPrimitiveValueToRecognizedODataType(object propertyValue, Type propertyType)
        {
            Debug.Assert(PrimitiveType.IsKnownNullableType(propertyType), "GetPrimitiveValue must be called only for primitive types");
            Debug.Assert(propertyValue == null || PrimitiveType.IsKnownType(propertyValue.GetType()), "GetPrimitiveValue method must be called for primitive values only");

            if (propertyValue == null)
            {
                return(null);
            }

            PrimitiveType primitiveType;

            PrimitiveType.TryGetPrimitiveType(propertyType, out primitiveType);
            Debug.Assert(primitiveType != null, "must be a known primitive type");

            // Do the conversion for types that are not supported by ODataLib e.g. char[], char, etc
            if (propertyType == typeof(Char) ||
                propertyType == typeof(Char[]) ||
                propertyType == typeof(Type) ||
                propertyType == typeof(Uri) ||
                propertyType == typeof(System.Xml.Linq.XDocument) ||
                propertyType == typeof(System.Xml.Linq.XElement))
            {
                return(primitiveType.TypeConverter.ToString(propertyValue));
            }
            else if (propertyType == typeof(DateTime))
            {
                return(PlatformHelper.ConvertDateTimeToDateTimeOffset((DateTime)propertyValue));
            }
#if !PORTABLELIB
            else if (propertyType.FullName == "System.Data.Linq.Binary")
            {
                // For System.Data.Linq.Binary, it is a delay loaded type. Hence checking it based on name.
                // PrimitiveType.IsKnownType checks for binary type based on name and assembly. Hence just
                // checking name here is sufficient, since any other type with the same name, but in different
                // assembly will return false for PrimitiveType.IsKnownNullableType.
                // Since ODataLib does not understand binary type, we need to convert the value to byte[].
                return(((BinaryTypeConverter)primitiveType.TypeConverter).ToArray(propertyValue));
            }
#endif
            else if (primitiveType.EdmTypeName == null)
            {
                // case StorageType.DateTimeOffset:
                // case StorageType.TimeSpan:
                // case StorageType.UInt16:
                // case StorageType.UInt32:
                // case StorageType.UInt64:
                // don't support reverse mappings for these types in this version
                // allows us to add real server support in the future without a
                // "breaking change" in the future client
                throw new NotSupportedException(Strings.ALinq_CantCastToUnsupportedPrimitive(propertyType.Name));
            }

            return(propertyValue);
        }
        /// <summary>
        /// Formats the literal without a type prefix, quotes, or escaping.
        /// </summary>
        /// <param name="value">The non-null value to format.</param>
        /// <returns>The formatted literal, without type marker or quotes.</returns>
        private static string FormatRawLiteral(object value)
        {
            Debug.Assert(value != null, "value != null");

            string stringValue = value as string;

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

            if (value is bool)
            {
                return(XmlConvert.ToString((bool)value));
            }

            if (value is byte)
            {
                return(XmlConvert.ToString((byte)value));
            }

#if ODATA_SERVICE || ODATA_CLIENT
            if (value is DateTime)
            {
                // Since the server/client supports DateTime values, convert the DateTime value
                // to DateTimeOffset and use XmlConvert to convert to String.
                // If datetime kind is unspecified, then treat it as UTC.
#if ODATA_SERVICE
                DateTimeOffset dto = WebUtil.ConvertDateTimeToDateTimeOffset((DateTime)value);
#elif ODATA_CLIENT
                DateTimeOffset dto = PlatformHelper.ConvertDateTimeToDateTimeOffset((DateTime)value);
#endif

                return(XmlConvert.ToString(dto));
            }
#endif

            if (value is decimal)
            {
                return(XmlConvert.ToString((decimal)value));
            }

            if (value is double)
            {
                string formattedDouble = XmlConvert.ToString((double)value);
                formattedDouble = SharedUtils.AppendDecimalMarkerToDouble(formattedDouble);
                return(formattedDouble);
            }

            if (value is Guid)
            {
                return(value.ToString());
            }

            if (value is short)
            {
                return(XmlConvert.ToString((Int16)value));
            }

            if (value is int)
            {
                return(XmlConvert.ToString((Int32)value));
            }

            if (value is long)
            {
                return(XmlConvert.ToString((Int64)value));
            }

            if (value is sbyte)
            {
                return(XmlConvert.ToString((SByte)value));
            }

            if (value is float)
            {
                return(XmlConvert.ToString((Single)value));
            }

            byte[] array = value as byte[];
            if (array != null)
            {
                return(ConvertByteArrayToKeyString(array));
            }

            if (value is Date)
            {
                return(value.ToString());
            }

            if (value is DateTimeOffset)
            {
                return(XmlConvert.ToString((DateTimeOffset)value));
            }

            if (value is TimeOfDay)
            {
                return(value.ToString());
            }

            if (value is TimeSpan)
            {
                return(EdmValueWriter.DurationAsXml((TimeSpan)value));
            }

            Geography geography = value as Geography;
            if (geography != null)
            {
                return(WellKnownTextSqlFormatter.Create(true).Write(geography));
            }

            Geometry geometry = value as Geometry;
            if (geometry != null)
            {
                return(WellKnownTextSqlFormatter.Create(true).Write(geometry));
            }

            ODataEnumValue enumValue = value as ODataEnumValue;
            if (enumValue != null)
            {
                return(enumValue.Value);
            }

            throw SharedUtils.CreateExceptionForUnconvertableType(value);
        }
Beispiel #3
0
        /// <summary>
        /// Converts the object to ODataValue, the result could be null, the original primitive object, ODataNullValue,
        /// ODataEnumValue, ODataCollectionValue, ODataResource, ODataEntityReferenceLinks, ODataEntityReferenceLinks, or
        /// a list of ODataResource.
        /// </summary>
        /// <param name="paramName">The name of the <see cref="UriOperationParameter"/>. Used for error reporting.</param>
        /// <param name="value">The value of the <see cref="UriOperationParameter"/>.</param>
        /// <param name="needsSpecialEscaping">True if the result need special escaping.</param>
        /// <param name="useEntityReference">If true, use entity reference, instead of entity to serialize the parameter.</param>
        /// <returns>The converted result.</returns>
        private object ConvertToODataValue(string paramName, object value, ref bool needsSpecialEscaping, bool useEntityReference)
        {
            Object valueInODataFormat = null;

            if (value == null)
            {
                needsSpecialEscaping = true;
            }
            else if (value is ODataNullValue)
            {
                valueInODataFormat   = value;
                needsSpecialEscaping = true;
            }
            else
            {
                ClientEdmModel model   = this.requestInfo.Model;
                IEdmType       edmType = model.GetOrCreateEdmType(value.GetType());
                Debug.Assert(edmType != null, "edmType != null");
                ClientTypeAnnotation typeAnnotation = model.GetClientTypeAnnotation(edmType);
                Debug.Assert(typeAnnotation != null, "typeAnnotation != null");
                switch (edmType.TypeKind)
                {
                case EdmTypeKind.Primitive:
                    // Client lib internal conversion to support DateTime
                    if (value is DateTime)
                    {
                        valueInODataFormat = PlatformHelper.ConvertDateTimeToDateTimeOffset((DateTime)value);
                    }
                    else
                    {
                        valueInODataFormat = value;
                    }

                    needsSpecialEscaping = true;
                    break;

                case EdmTypeKind.Enum:
                    string typeNameInEdm = this.requestInfo.GetServerTypeName(model.GetClientTypeAnnotation(edmType));
                    valueInODataFormat =
                        new ODataEnumValue(
                            ClientTypeUtil.GetEnumValuesString(value.ToString(), typeAnnotation.ElementType),
                            typeNameInEdm ?? typeAnnotation.ElementTypeName);
                    needsSpecialEscaping = true;

                    break;

                case EdmTypeKind.Collection:
                    IEdmCollectionType edmCollectionType = edmType as IEdmCollectionType;
                    Debug.Assert(edmCollectionType != null, "edmCollectionType != null");
                    IEdmTypeReference itemTypeReference = edmCollectionType.ElementType;
                    Debug.Assert(itemTypeReference != null, "itemTypeReference != null");
                    ClientTypeAnnotation itemTypeAnnotation =
                        model.GetClientTypeAnnotation(itemTypeReference.Definition);
                    Debug.Assert(itemTypeAnnotation != null, "itemTypeAnnotation != null");

                    valueInODataFormat = ConvertToCollectionValue(paramName, value, itemTypeAnnotation, useEntityReference);
                    break;

                case EdmTypeKind.Complex:
                case EdmTypeKind.Entity:
                    Debug.Assert(edmType.TypeKind == EdmTypeKind.Complex || value != null, "edmType.TypeKind == EdmTypeKind.Complex || value != null");
                    Debug.Assert(typeAnnotation != null, "typeAnnotation != null");
                    valueInODataFormat = ConvertToEntityValue(value, typeAnnotation.ElementType, useEntityReference);
                    break;

                default:
                    // EdmTypeKind.Row
                    // EdmTypeKind.EntityReference
                    throw new NotSupportedException(Strings.Serializer_InvalidParameterType(paramName, edmType.TypeKind));
                }

                Debug.Assert(valueInODataFormat != null, "valueInODataFormat != null");
            }

            return(valueInODataFormat);
        }