diff --git a/Src/Newtonsoft.Json.Tests/Issues/Issue1307.cs b/Src/Newtonsoft.Json.Tests/Issues/Issue1307.cs new file mode 100644 index 00000000..a2acd738 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Issues/Issue1307.cs @@ -0,0 +1,112 @@ +#region License +// Copyright (c) 2007 James Newton-King +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +#if DNXCORE50 +using Xunit; +using Test = Xunit.FactAttribute; +using Assert = Newtonsoft.Json.Tests.XUnitAssert; +#else +using NUnit.Framework; +#endif + +namespace Newtonsoft.Json.Tests.Issues +{ + [TestFixture] + public class Issue1307 : TestFixtureBase + { + public class MyOtherClass + { + [JsonConverter(typeof(MyJsonConverter))] + public MyClass2 InstanceOfMyClass { get; set; } + } + + public class MyClass2 + { + public int[] Dummy { get; set; } + } + + internal class MyJsonConverter : JsonConverter + { + static private readonly JsonLoadSettings _jsonLoadSettings = new JsonLoadSettings { CommentHandling = CommentHandling.Ignore }; + + public override bool CanConvert(Type objectType) + { + return typeof(MyClass2).Equals(objectType); + } + + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + var token = JToken.Load(reader, _jsonLoadSettings); + + if (token.Type == JTokenType.Object) + { + return token.ToObject(); + } + else if (token.Type == JTokenType.Array) + { + var result = new MyClass2(); + result.Dummy = token.Select(t => (int)t).ToArray(); + return result; + } + else if (token.Type == JTokenType.Comment) + { + throw new InvalidProgramException(); + } + return existingValue; + } + + #region Do not use this converter for writing. + + public override bool CanWrite { get { return false; } } + + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + throw new NotSupportedException(); + } + + #endregion + + } + + [Test] + public void Test() + { + string json = @"{ + ""instanceOfMyClass"": + /* Comment explaining that this is a legacy data contract: */ + [ 1, 2, 3 ] +}"; + + var c = JsonConvert.DeserializeObject(json); + Assert.AreEqual(3, c.InstanceOfMyClass.Dummy.Length); + } + } +} diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs index 0fe86bd2..ed55bc11 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs @@ -59,6 +59,18 @@ namespace Newtonsoft.Json.Tests.Linq Assert.AreEqual(10000000000000000000d, reader.ReadAsDouble()); Assert.IsTrue(reader.Read()); } + + [Test] + public void ConvertBigIntegerToDecimal() + { + var jObject = JObject.Parse("{ maxValue:10000000000000000000}"); + + JsonReader reader = jObject.CreateReader(); + Assert.IsTrue(reader.Read()); + Assert.IsTrue(reader.Read()); + Assert.AreEqual(10000000000000000000m, reader.ReadAsDecimal()); + Assert.IsTrue(reader.Read()); + } #endif [Test] diff --git a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs index 6105664d..b1fc6395 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs @@ -52,6 +52,22 @@ namespace Newtonsoft.Json.Tests.Linq [TestFixture] public class LinqToJsonTest : TestFixtureBase { +#if !(NET20 || NET35 || PORTABLE40 || PORTABLE) || NETSTANDARD1_3 + public class DemoClass + { + public decimal maxValue; + } + + [Test] + public void ToObjectDecimal() + { + var jArray = JArray.Parse("[{ maxValue:10000000000000000000 }]"); + var list = jArray.ToObject>(); + + Assert.AreEqual(10000000000000000000m, list[0].maxValue); + } +#endif + [Test] public void FromObjectGuid() { diff --git a/Src/Newtonsoft.Json/JsonReader.cs b/Src/Newtonsoft.Json/JsonReader.cs index d2650aa4..2f771e87 100644 --- a/Src/Newtonsoft.Json/JsonReader.cs +++ b/Src/Newtonsoft.Json/JsonReader.cs @@ -751,7 +751,19 @@ namespace Newtonsoft.Json case JsonToken.Float: if (!(Value is decimal)) { - SetToken(JsonToken.Float, Convert.ToDecimal(Value, CultureInfo.InvariantCulture), false); + decimal d; +#if HAVE_BIG_INTEGER + if (Value is BigInteger) + { + d = (decimal)(BigInteger)Value; + } + else +#endif + { + d = Convert.ToDecimal(Value, CultureInfo.InvariantCulture); + } + + SetToken(JsonToken.Float, d, false); } return (decimal)Value; diff --git a/Src/Newtonsoft.Json/Linq/CommentHandling.cs b/Src/Newtonsoft.Json/Linq/CommentHandling.cs index d178df8e..ac179dd3 100644 --- a/Src/Newtonsoft.Json/Linq/CommentHandling.cs +++ b/Src/Newtonsoft.Json/Linq/CommentHandling.cs @@ -1,4 +1,29 @@ -namespace Newtonsoft.Json.Linq +#region License +// Copyright (c) 2007 James Newton-King +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +#endregion + +namespace Newtonsoft.Json.Linq { /// /// Specifies how JSON comments are handled when loading JSON. diff --git a/Src/Newtonsoft.Json/Linq/JToken.cs b/Src/Newtonsoft.Json/Linq/JToken.cs index d076b95a..05dfa752 100644 --- a/Src/Newtonsoft.Json/Linq/JToken.cs +++ b/Src/Newtonsoft.Json/Linq/JToken.cs @@ -2114,16 +2114,25 @@ namespace Newtonsoft.Json.Linq { ValidationUtils.ArgumentNotNull(reader, nameof(reader)); + bool hasContent; if (reader.TokenType == JsonToken.None) { - bool hasContent = (settings != null && settings.CommentHandling == CommentHandling.Ignore) + hasContent = (settings != null && settings.CommentHandling == CommentHandling.Ignore) ? reader.ReadAndMoveToContent() : reader.Read(); + } + else if (reader.TokenType == JsonToken.Comment && settings?.CommentHandling == CommentHandling.Ignore) + { + hasContent = reader.ReadAndMoveToContent(); + } + else + { + hasContent = true; + } - if (!hasContent) - { - throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader."); - } + if (!hasContent) + { + throw JsonReaderException.Create(reader, "Error reading JToken from JsonReader."); } IJsonLineInfo lineInfo = reader as IJsonLineInfo;