Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to override Primitive Serialization and deserialization of Payload. #108 #139

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 1 addition & 194 deletions src/Microsoft.OData.Core/JsonLight/ODataJsonLightReaderUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,86 +115,7 @@ internal static object ConvertValue(
return null;
}

try
{
Type targetType = EdmLibraryExtensions.GetPrimitiveClrType(primitiveTypeReference.PrimitiveDefinition(), false);

string stringValue = value as string;
if (stringValue != null)
{
return ConvertStringValue(stringValue, targetType);
}
else if (value is Int32)
{
return ConvertInt32Value((int)value, targetType, primitiveTypeReference);
}
else if (value is Decimal)
{
Decimal decimalValue = (Decimal)value;
if (targetType == typeof(Int64))
{
return Convert.ToInt64(decimalValue);
}

if (targetType == typeof(Double))
{
return Convert.ToDouble(decimalValue);
}

if (targetType == typeof(Single))
{
return Convert.ToSingle(decimalValue);
}

if (targetType != typeof(Decimal))
{
throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertDecimal(primitiveTypeReference.ODataFullName()));
}
}
else if (value is Double)
{
Double doubleValue = (Double)value;
if (targetType == typeof(Single))
{
return Convert.ToSingle(doubleValue);
}

if (targetType != typeof(Double))
{
throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertDouble(primitiveTypeReference.ODataFullName()));
}
}
else if (value is bool)
{
if (targetType != typeof(bool))
{
throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertBoolean(primitiveTypeReference.ODataFullName()));
}
}
else if (value is DateTime)
{
if (targetType != typeof(DateTime))
{
throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertDateTime(primitiveTypeReference.ODataFullName()));
}
}
else if (value is DateTimeOffset)
{
if (targetType != typeof(DateTimeOffset))
{
throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertDateTimeOffset(primitiveTypeReference.ODataFullName()));
}
}
}
catch (Exception e)
{
if (!ExceptionUtils.IsCatchableExceptionType(e))
{
throw;
}

throw ReaderValidationUtils.GetPrimitiveTypeConversionException(primitiveTypeReference, e, value.ToString());
}
value = PrimitivePayloadValueConverters.PrimitivePayloadValueConverterProvider.GetPrimitivePayloadValueConverter().ConvertFromPayloadValue(value, primitiveTypeReference, messageReaderSettings);

// otherwise just return the value without doing any conversion
return value;
Expand Down Expand Up @@ -303,119 +224,5 @@ internal static string GetPayloadTypeName(object payloadItem)

throw new ODataException(ODataErrorStrings.General_InternalError(InternalErrorCodes.ODataJsonLightReader_ReadEntryStart));
}

/// <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 perserve consistence
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>
/// Converts the given JSON int value to the expected type as per OData conversion rules for JSON values.
/// </summary>
/// <param name="intValue">Int32 value to the converted.</param>
/// <param name="targetType">Target type to which the int value needs to be converted.</param>
/// <param name="primitiveTypeReference">Type reference to which the value needs to be converted.</param>
/// <returns>Object which is in sync with the property type.</returns>
private static object ConvertInt32Value(int intValue, Type targetType, IEdmPrimitiveTypeReference primitiveTypeReference)
{
if (targetType == typeof(Int16))
{
return Convert.ToInt16(intValue);
}

if (targetType == typeof(Byte))
{
return Convert.ToByte(intValue);
}

if (targetType == typeof(SByte))
{
return Convert.ToSByte(intValue);
}

if (targetType == typeof(Single))
{
return Convert.ToSingle(intValue);
}

if (targetType == typeof(Double))
{
return Convert.ToDouble(intValue);
}

if (targetType == typeof(Decimal))
{
return Convert.ToDecimal(intValue);
}

if (targetType == typeof(Int64))
{
return Convert.ToInt64(intValue);
}

if (targetType != typeof(Int32))
{
throw new ODataException(ODataErrorStrings.ODataJsonReaderUtils_CannotConvertInt32(primitiveTypeReference.ODataFullName()));
}

return intValue;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -346,10 +346,7 @@ public void WritePrimitiveValue(

IEdmPrimitiveTypeReference actualTypeReference = EdmLibraryExtensions.GetPrimitiveTypeReference(value.GetType());

if (expectedTypeReference != null)
{
ValidationUtils.ValidateIsExpectedPrimitiveType(value, actualTypeReference, expectedTypeReference, !this.JsonLightOutputContext.MessageWriterSettings.EnableFullValidation);
}
value = PrimitivePayloadValueConverters.PrimitivePayloadValueConverterProvider.GetPrimitivePayloadValueConverter().ConvertToPayloadValue(value, expectedTypeReference, this.JsonLightOutputContext.MessageWriterSettings);

if (actualTypeReference != null && actualTypeReference.IsSpatial())
{
Expand Down
3 changes: 3 additions & 0 deletions src/Microsoft.OData.Core/Microsoft.OData.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,9 @@
<Compile Include="ODataWriterBehavior.cs" />
<Compile Include="ODataWriterCore.cs" />
<Compile Include="PrimitiveConverter.cs" />
<Compile Include="PrimitivePayloadValueConverters\PrimitivePayloadValueConverterProvider.cs" />
<Compile Include="PrimitivePayloadValueConverters\DefaultPrimitivePayloadValueConverter.cs" />
<Compile Include="PrimitivePayloadValueConverters\IPrimitivePayloadValueConverter.cs" />
<Compile Include="ProjectedPropertiesAnnotation.cs" />
<Compile Include="Query\ExpressionConstants.cs" />
<Compile Include="Query\ODataUriConversionUtils.cs" />
Expand Down
Loading