-Fixed roundtripping double.MaxValue and float.MaxValue as dictionary keys

This commit is contained in:
James Newton-King
2016-12-10 17:23:43 +13:00
parent 3c1fdf9fdd
commit 133bbc2d38
2 changed files with 72 additions and 18 deletions
@@ -63,6 +63,39 @@ namespace Newtonsoft.Json.Tests.Serialization
[TestFixture] [TestFixture]
public class JsonSerializerCollectionsTests : TestFixtureBase public class JsonSerializerCollectionsTests : TestFixtureBase
{ {
[Test]
public void DoubleKey_WholeValue()
{
Dictionary<double, int> dictionary = new Dictionary<double, int> { { 1d, 1 } };
string output = JsonConvert.SerializeObject(dictionary);
Assert.AreEqual(@"{""1"":1}", output);
Dictionary<double, int> deserializedValue = JsonConvert.DeserializeObject<Dictionary<double, int>>(output);
Assert.AreEqual(1d, deserializedValue.First().Key);
}
[Test]
public void DoubleKey_MaxValue()
{
Dictionary<double, int> dictionary = new Dictionary<double, int> { { double.MaxValue, 1 } };
string output = JsonConvert.SerializeObject(dictionary);
Assert.AreEqual(@"{""1.7976931348623157E+308"":1}", output);
Dictionary<double, int> deserializedValue = JsonConvert.DeserializeObject<Dictionary<double, int>>(output);
Assert.AreEqual(double.MaxValue, deserializedValue.First().Key);
}
[Test]
public void FloatKey_MaxValue()
{
Dictionary<float, int> dictionary = new Dictionary<float, int> { { float.MaxValue, 1 } };
string output = JsonConvert.SerializeObject(dictionary);
Assert.AreEqual(@"{""3.40282347E+38"":1}", output);
Dictionary<float, int> deserializedValue = JsonConvert.DeserializeObject<Dictionary<float, int>>(output);
Assert.AreEqual(float.MaxValue, deserializedValue.First().Key);
}
public class TestCollectionPrivateParameterized : IEnumerable<int> public class TestCollectionPrivateParameterized : IEnumerable<int>
{ {
private readonly List<int> _bars; private readonly List<int> _bars;
@@ -1130,28 +1130,49 @@ namespace Newtonsoft.Json.Serialization
if (contract.ContractType == JsonContractType.Primitive) if (contract.ContractType == JsonContractType.Primitive)
{ {
JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract)contract; JsonPrimitiveContract primitiveContract = (JsonPrimitiveContract)contract;
if (primitiveContract.TypeCode == PrimitiveTypeCode.DateTime || primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeNullable) switch (primitiveContract.TypeCode)
{ {
DateTime dt = DateTimeUtils.EnsureDateTime((DateTime)name, writer.DateTimeZoneHandling); case PrimitiveTypeCode.DateTime:
case PrimitiveTypeCode.DateTimeNullable:
{
DateTime dt = DateTimeUtils.EnsureDateTime((DateTime)name, writer.DateTimeZoneHandling);
escape = false; escape = false;
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
DateTimeUtils.WriteDateTimeString(sw, dt, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); DateTimeUtils.WriteDateTimeString(sw, dt, writer.DateFormatHandling, writer.DateFormatString, writer.Culture);
return sw.ToString(); return sw.ToString();
} }
#if !NET20 #if !NET20
else if (primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeOffset || primitiveContract.TypeCode == PrimitiveTypeCode.DateTimeOffsetNullable) case PrimitiveTypeCode.DateTimeOffset:
{ case PrimitiveTypeCode.DateTimeOffsetNullable:
escape = false; {
StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); escape = false;
DateTimeUtils.WriteDateTimeOffsetString(sw, (DateTimeOffset)name, writer.DateFormatHandling, writer.DateFormatString, writer.Culture); StringWriter sw = new StringWriter(CultureInfo.InvariantCulture);
return sw.ToString(); DateTimeUtils.WriteDateTimeOffsetString(sw, (DateTimeOffset)name, writer.DateFormatHandling, writer.DateFormatString, writer.Culture);
} return sw.ToString();
}
#endif #endif
else case PrimitiveTypeCode.Double:
{ case PrimitiveTypeCode.DoubleNullable:
escape = true; {
return Convert.ToString(name, CultureInfo.InvariantCulture); double d = (double)name;
escape = false;
return d.ToString("R", CultureInfo.InvariantCulture);
}
case PrimitiveTypeCode.Single:
case PrimitiveTypeCode.SingleNullable:
{
float f = (float)name;
escape = false;
return f.ToString("R", CultureInfo.InvariantCulture);
}
default:
{
escape = true;
return Convert.ToString(name, CultureInfo.InvariantCulture);
}
} }
} }
else if (TryConvertToString(name, name.GetType(), out propertyName)) else if (TryConvertToString(name, name.GetType(), out propertyName))