/// <summary> /// Converts the given JSON string value to the expected type as per OData conversion rules for JSON values. /// </summary> /// <param name="stringValue">String value to the converted.</param> /// <param name="targetType">Target type to which the string value needs to be converted.</param> /// <returns>Object which is in sync with the target type.</returns> private static object ConvertStringValue(string stringValue, Type targetType) { // COMPAT 53: Support for System.Data.Linq.Binary and System.Xml.Linq.XElement if (targetType == typeof(byte[])) { return(Convert.FromBase64String(stringValue)); } if (targetType == typeof(Guid)) { return(new Guid(stringValue)); } // Convert.ChangeType does not support TimeSpan. if (targetType == typeof(TimeSpan)) { return(EdmValueParser.ParseDuration(stringValue)); } // Date if (targetType == typeof(Date)) { return(PlatformHelper.ConvertStringToDate(stringValue)); } // Time if (targetType == typeof(TimeOfDay)) { return(PlatformHelper.ConvertStringToTimeOfDay(stringValue)); } // DateTimeOffset needs to be read using the XML rules (as per the JSON Light spec). if (targetType == typeof(DateTimeOffset)) { return(PlatformHelper.ConvertStringToDateTimeOffset(stringValue)); } if (targetType == typeof(Double) || targetType == typeof(Single)) { // Accept Infinity and -Infinity to preserve consistency if (stringValue == CultureInfo.InvariantCulture.NumberFormat.PositiveInfinitySymbol) { stringValue = JsonValueUtils.ODataJsonPositiveInfinitySymbol; } else if (stringValue == CultureInfo.InvariantCulture.NumberFormat.NegativeInfinitySymbol) { stringValue = JsonValueUtils.ODataJsonNegativeInfinitySymbol; } return(Convert.ChangeType(stringValue, targetType, JsonValueUtils.ODataNumberFormatInfo)); } // For string types, we support conversion to all possible primitive types return(Convert.ChangeType(stringValue, targetType, CultureInfo.InvariantCulture)); }
/// <summary> /// Attempts to parse a TimeOfDay value from the specified text. /// </summary> /// <param name="value">Input string</param> /// <param name="result">The TimeOfDay resulting from parsing the string value</param> /// <returns>true if the value was parsed successfully, false otherwise</returns> internal static bool TryParseTimeOfDay(string value, out TimeOfDay?result) { try { result = PlatformHelper.ConvertStringToTimeOfDay(value); return(true); } catch (FormatException) { result = null; return(false); } }
/// <summary> /// Converts a string to a TimeOfDay value. /// </summary> /// <param name="text">String text to convert.</param> /// <param name="targetValue">After invocation, converted value.</param> /// <returns>true if the value was converted; false otherwise.</returns> internal static bool TryUriStringToTimeOfDay(string text, out TimeOfDay targetValue) { targetValue = default(TimeOfDay); try { targetValue = PlatformHelper.ConvertStringToTimeOfDay(text); return(true); } catch (FormatException) { return(false); } }
/// <summary> /// Create an instance of primitive type from a string representation /// </summary> /// <param name="text">The string representation</param> /// <returns>An instance of primitive type</returns> internal override object Parse(string text) { return(PlatformHelper.ConvertStringToTimeOfDay(text)); }
internal static object ConvertStringToPrimitive(string text, IEdmPrimitiveTypeReference targetTypeReference) { Debug.Assert(text != null, "text != null"); Debug.Assert(targetTypeReference != null, "targetTypeReference != null"); try { EdmPrimitiveTypeKind primitiveKind = targetTypeReference.PrimitiveKind(); switch (primitiveKind) { case EdmPrimitiveTypeKind.Binary: return(Convert.FromBase64String(text)); case EdmPrimitiveTypeKind.Boolean: return(ConvertXmlBooleanValue(text)); case EdmPrimitiveTypeKind.Byte: return(XmlConvert.ToByte(text)); case EdmPrimitiveTypeKind.DateTimeOffset: return(PlatformHelper.ConvertStringToDateTimeOffset(text)); case EdmPrimitiveTypeKind.Decimal: return(XmlConvert.ToDecimal(text)); case EdmPrimitiveTypeKind.Double: return(XmlConvert.ToDouble(text)); case EdmPrimitiveTypeKind.Guid: return(new Guid(text)); case EdmPrimitiveTypeKind.Int16: return(XmlConvert.ToInt16(text)); case EdmPrimitiveTypeKind.Int32: return(XmlConvert.ToInt32(text)); case EdmPrimitiveTypeKind.Int64: return(XmlConvert.ToInt64(text)); case EdmPrimitiveTypeKind.SByte: return(XmlConvert.ToSByte(text)); case EdmPrimitiveTypeKind.Single: return(XmlConvert.ToSingle(text)); case EdmPrimitiveTypeKind.String: return(text); case EdmPrimitiveTypeKind.Duration: return(EdmValueParser.ParseDuration(text)); case EdmPrimitiveTypeKind.Date: return(PlatformHelper.ConvertStringToDate(text)); case EdmPrimitiveTypeKind.TimeOfDay: return(PlatformHelper.ConvertStringToTimeOfDay(text)); case EdmPrimitiveTypeKind.Stream: case EdmPrimitiveTypeKind.None: case EdmPrimitiveTypeKind.Geography: case EdmPrimitiveTypeKind.GeographyCollection: case EdmPrimitiveTypeKind.GeographyPoint: case EdmPrimitiveTypeKind.GeographyLineString: case EdmPrimitiveTypeKind.GeographyPolygon: case EdmPrimitiveTypeKind.GeometryCollection: case EdmPrimitiveTypeKind.GeographyMultiPolygon: case EdmPrimitiveTypeKind.GeographyMultiLineString: case EdmPrimitiveTypeKind.GeographyMultiPoint: case EdmPrimitiveTypeKind.Geometry: case EdmPrimitiveTypeKind.GeometryPoint: case EdmPrimitiveTypeKind.GeometryLineString: case EdmPrimitiveTypeKind.GeometryPolygon: case EdmPrimitiveTypeKind.GeometryMultiPolygon: case EdmPrimitiveTypeKind.GeometryMultiLineString: case EdmPrimitiveTypeKind.GeometryMultiPoint: default: // Note that Astoria supports XElement and Binary as well, but they are serialized as string or byte[] // and the metadata will actually talk about string and byte[] as well. Astoria will perform the conversion if necessary. throw new ODataException(Strings.General_InternalError(InternalErrorCodes.AtomValueUtils_ConvertStringToPrimitive)); } } catch (Exception e) { if (!ExceptionUtils.IsCatchableExceptionType(e)) { throw; } throw ReaderValidationUtils.GetPrimitiveTypeConversionException(targetTypeReference, e, text); } }