-Fixed documentation typo
-Fixed error when serializing some interfaces with hidden properties -Fixed some large integers being incorrectly read from JSON
This commit is contained in:
@@ -49,10 +49,11 @@
|
||||
serialized by default but can be ignored with the JsonIgnoreAttribute, Json.NET's default behavior) or
|
||||
fields (all public and private fields are serialized and properties are ignored).</para>
|
||||
<para>Json.NET serializes .NET classes that implement IEnumerable as a JSON array populated with the
|
||||
IEnumerable values. Placing the JsonPropertyAttribute overrides this behavior and forces the serializer
|
||||
to serialize the class's fields and properties.</para>
|
||||
<para>The DataContractAttribute can be used as substitute for JsonObjectAttribute. The
|
||||
DataContractAttribute will default member serialization to opt-in.</para>
|
||||
IEnumerable values. Placing the <codeEntityReference>T:Newtonsoft.Json.JsonObjectAttribute</codeEntityReference>
|
||||
overrides this behavior and forces the serializer to serialize the class's fields and properties.</para>
|
||||
<para>The <codeEntityReference>T:System.Runtime.Serialization.DataContractAttribute</codeEntityReference>
|
||||
can be used as substitute for JsonObjectAttribute. The DataContractAttribute will default member
|
||||
serialization to opt-in.</para>
|
||||
</content>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -3248,6 +3248,55 @@ null//comment
|
||||
},
|
||||
"Unexpected character encountered while parsing value: !. Path 'frameworks.dnxcore50.dependencies.['System.Xml.ReaderWriter'].source', line 6, position 21.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Fix this next major version")]
|
||||
public void LinePositionOnNewLine()
|
||||
{
|
||||
string json1 = "{'a':'bc'}";
|
||||
|
||||
JsonTextReader r = new JsonTextReader(new StringReader(json1));
|
||||
|
||||
Assert.IsTrue(r.Read());
|
||||
Assert.AreEqual(1, r.LineNumber);
|
||||
Assert.AreEqual(1, r.LinePosition);
|
||||
|
||||
Assert.IsTrue(r.Read());
|
||||
Assert.AreEqual(1, r.LineNumber);
|
||||
Assert.AreEqual(5, r.LinePosition);
|
||||
|
||||
Assert.IsTrue(r.Read());
|
||||
Assert.AreEqual(1, r.LineNumber);
|
||||
Assert.AreEqual(9, r.LinePosition);
|
||||
|
||||
Assert.IsTrue(r.Read());
|
||||
Assert.AreEqual(1, r.LineNumber);
|
||||
Assert.AreEqual(10, r.LinePosition);
|
||||
|
||||
Assert.IsFalse(r.Read());
|
||||
|
||||
string json2 = "\n{'a':'bc'}";
|
||||
|
||||
r = new JsonTextReader(new StringReader(json2));
|
||||
|
||||
Assert.IsTrue(r.Read());
|
||||
Assert.AreEqual(2, r.LineNumber);
|
||||
Assert.AreEqual(1, r.LinePosition);
|
||||
|
||||
Assert.IsTrue(r.Read());
|
||||
Assert.AreEqual(2, r.LineNumber);
|
||||
Assert.AreEqual(5, r.LinePosition);
|
||||
|
||||
Assert.IsTrue(r.Read());
|
||||
Assert.AreEqual(2, r.LineNumber);
|
||||
Assert.AreEqual(9, r.LinePosition);
|
||||
|
||||
Assert.IsTrue(r.Read());
|
||||
Assert.AreEqual(2, r.LineNumber);
|
||||
Assert.AreEqual(10, r.LinePosition);
|
||||
|
||||
Assert.IsFalse(r.Read());
|
||||
}
|
||||
}
|
||||
|
||||
public class ToggleReaderError : TextReader
|
||||
|
||||
@@ -456,6 +456,7 @@
|
||||
<Compile Include="Utilities\ExpressionReflectionDelegateFactoryTests.cs" />
|
||||
<Compile Include="Utilities\LateboundReflectionDelegateFactoryTests.cs" />
|
||||
<Compile Include="Utilities\ReflectionUtilsTests.cs" />
|
||||
<Compile Include="Utilities\ConvertUtilsTests.cs" />
|
||||
<Compile Include="Utilities\StringUtilsTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -95,6 +95,111 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
[TestFixture]
|
||||
public class JsonSerializerTest : TestFixtureBase
|
||||
{
|
||||
public interface ISubclassBase
|
||||
{
|
||||
int ID { get; set; }
|
||||
string Name { get; set; }
|
||||
bool P1 { get; }
|
||||
}
|
||||
public interface ISubclass : ISubclassBase
|
||||
{
|
||||
new bool P1 { get; set; }
|
||||
int P2 { get; set; }
|
||||
}
|
||||
public interface IMainClass
|
||||
{
|
||||
int ID { get; set; }
|
||||
string Name { get; set; }
|
||||
ISubclass Subclass { get; set; }
|
||||
}
|
||||
|
||||
public class Subclass : ISubclass
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool P1 { get; set; }
|
||||
public int P2 { get; set; }
|
||||
}
|
||||
public class MainClass : IMainClass
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string Name { get; set; }
|
||||
public ISubclass Subclass { get; set; }
|
||||
}
|
||||
|
||||
public class MyFactory
|
||||
{
|
||||
public static ISubclass InstantiateSubclass()
|
||||
{
|
||||
return new Subclass
|
||||
{
|
||||
ID = 123,
|
||||
Name = "ABC",
|
||||
P1 = true,
|
||||
P2 = 44
|
||||
};
|
||||
}
|
||||
public static IMainClass InstantiateManiClass()
|
||||
{
|
||||
return new MainClass
|
||||
{
|
||||
ID = 567,
|
||||
Name = "XYZ",
|
||||
Subclass = InstantiateSubclass()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeInterfaceWithHiddenProperties()
|
||||
{
|
||||
var mySubclass = MyFactory.InstantiateSubclass();
|
||||
var myMainClass = MyFactory.InstantiateManiClass();
|
||||
|
||||
//Class implementing interface with hidden members - flat object.
|
||||
var strJsonSubclass = JsonConvert.SerializeObject(mySubclass, Formatting.Indented);
|
||||
|
||||
StringAssert.AreEqual(@"{
|
||||
""ID"": 123,
|
||||
""Name"": ""ABC"",
|
||||
""P1"": true,
|
||||
""P2"": 44
|
||||
}", strJsonSubclass);
|
||||
|
||||
//Class implementing interface with hidden members - member of another class.
|
||||
var strJsonMainClass = JsonConvert.SerializeObject(myMainClass, Formatting.Indented);
|
||||
|
||||
StringAssert.AreEqual(@"{
|
||||
""ID"": 567,
|
||||
""Name"": ""XYZ"",
|
||||
""Subclass"": {
|
||||
""ID"": 123,
|
||||
""Name"": ""ABC"",
|
||||
""P1"": true,
|
||||
""P2"": 44
|
||||
}
|
||||
}", strJsonMainClass);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LargeIntegerAsString()
|
||||
{
|
||||
Console.WriteLine("Sending in: \n43443333222211111117");
|
||||
var largeBrokenNumber = JsonConvert.DeserializeObject<Foo64>("{\"Blah\": 43443333222211111117 }");
|
||||
Console.WriteLine(largeBrokenNumber.Blah);
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
Console.WriteLine("Sending in: \n53443333222211111117");
|
||||
var largeOddWorkingNumber = JsonConvert.DeserializeObject<Foo64>("{\"Blah\": 53443333222211111117 }");
|
||||
Console.WriteLine(largeOddWorkingNumber.Blah);
|
||||
}
|
||||
|
||||
public class Foo64
|
||||
{
|
||||
public string Blah { get; set; }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CaseInsensitiveRequiredPropertyConstructorCreation()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
#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
|
||||
|
||||
#if NETFX_CORE
|
||||
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
||||
using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
|
||||
using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
|
||||
#elif DNXCORE50
|
||||
using Xunit;
|
||||
using Test = Xunit.FactAttribute;
|
||||
using Assert = Newtonsoft.Json.Tests.XUnitAssert;
|
||||
#else
|
||||
using NUnit.Framework;
|
||||
#endif
|
||||
using Newtonsoft.Json.Utilities;
|
||||
|
||||
namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
[TestFixture]
|
||||
public class ConvertUtilsTests : TestFixtureBase
|
||||
{
|
||||
[Test]
|
||||
public void Int64TryParse()
|
||||
{
|
||||
long l;
|
||||
char[] c = "43443333222211111117".ToCharArray();
|
||||
ParseResult result = ConvertUtils.Int64TryParse(c, 0, c.Length, out l);
|
||||
Assert.AreEqual(ParseResult.Overflow, result);
|
||||
|
||||
c = "9223372036854775807".ToCharArray();
|
||||
result = ConvertUtils.Int64TryParse(c, 0, c.Length, out l);
|
||||
Assert.AreEqual(ParseResult.Success, result);
|
||||
Assert.AreEqual(9223372036854775807L, l);
|
||||
|
||||
c = "9223372036854775808".ToCharArray();
|
||||
result = ConvertUtils.Int64TryParse(c, 0, c.Length, out l);
|
||||
Assert.AreEqual(ParseResult.Overflow, result);
|
||||
|
||||
for (int i = 3; i < 10; i++)
|
||||
{
|
||||
c = ("9" + i + "23372036854775807").ToCharArray();
|
||||
result = ConvertUtils.Int64TryParse(c, 0, c.Length, out l);
|
||||
Assert.AreEqual(ParseResult.Overflow, result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
c = "-9223372036854775808".ToCharArray();
|
||||
result = ConvertUtils.Int64TryParse(c, 0, c.Length, out l);
|
||||
Assert.AreEqual(ParseResult.Success, result);
|
||||
Assert.AreEqual(-9223372036854775808L, l);
|
||||
|
||||
c = "-9223372036854775809".ToCharArray();
|
||||
result = ConvertUtils.Int64TryParse(c, 0, c.Length, out l);
|
||||
Assert.AreEqual(ParseResult.Overflow, result);
|
||||
|
||||
for (int i = 3; i < 10; i++)
|
||||
{
|
||||
c = ("-9" + i + "23372036854775808").ToCharArray();
|
||||
result = ConvertUtils.Int64TryParse(c, 0, c.Length, out l);
|
||||
Assert.AreEqual(ParseResult.Overflow, result);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Int32TryParse()
|
||||
{
|
||||
int i;
|
||||
char[] c = "43443333227".ToCharArray();
|
||||
ParseResult result = ConvertUtils.Int32TryParse(c, 0, c.Length, out i);
|
||||
Assert.AreEqual(ParseResult.Overflow, result);
|
||||
|
||||
c = "2147483647".ToCharArray();
|
||||
result = ConvertUtils.Int32TryParse(c, 0, c.Length, out i);
|
||||
Assert.AreEqual(ParseResult.Success, result);
|
||||
Assert.AreEqual(2147483647, i);
|
||||
|
||||
c = "2147483648".ToCharArray();
|
||||
result = ConvertUtils.Int32TryParse(c, 0, c.Length, out i);
|
||||
Assert.AreEqual(ParseResult.Overflow, result);
|
||||
|
||||
for (int j = 2; j < 10; j++)
|
||||
{
|
||||
c = ("2" + j + "47483647").ToCharArray();
|
||||
result = ConvertUtils.Int32TryParse(c, 0, c.Length, out i);
|
||||
Assert.AreEqual(ParseResult.Overflow, result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
c = "-2147483648".ToCharArray();
|
||||
result = ConvertUtils.Int32TryParse(c, 0, c.Length, out i);
|
||||
Assert.AreEqual(ParseResult.Success, result);
|
||||
Assert.AreEqual(-2147483648, i);
|
||||
|
||||
c = "-2147483649".ToCharArray();
|
||||
result = ConvertUtils.Int32TryParse(c, 0, c.Length, out i);
|
||||
Assert.AreEqual(ParseResult.Overflow, result);
|
||||
|
||||
for (int j = 3; j < 10; j++)
|
||||
{
|
||||
c = ("-2" + j + "47483648").ToCharArray();
|
||||
result = ConvertUtils.Int32TryParse(c, 0, c.Length, out i);
|
||||
Assert.AreEqual(ParseResult.Overflow, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
/// <returns>The property name camel cased.</returns>
|
||||
protected override string ResolvePropertyName(string propertyName)
|
||||
{
|
||||
// lower case the first letter of the passed in name
|
||||
// lower case the first letter (or more) of the passed in name
|
||||
return StringUtils.ToCamelCase(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,13 +85,15 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
if (property.DeclaringType != null && existingProperty.DeclaringType != null)
|
||||
{
|
||||
if (property.DeclaringType.IsSubclassOf(existingProperty.DeclaringType))
|
||||
if (property.DeclaringType.IsSubclassOf(existingProperty.DeclaringType)
|
||||
|| (existingProperty.DeclaringType.IsInterface && property.DeclaringType.ImplementInterface(existingProperty.DeclaringType)))
|
||||
{
|
||||
// current property is on a derived class and hides the existing
|
||||
Remove(existingProperty);
|
||||
duplicateProperty = false;
|
||||
}
|
||||
if (existingProperty.DeclaringType.IsSubclassOf(property.DeclaringType))
|
||||
if (existingProperty.DeclaringType.IsSubclassOf(property.DeclaringType)
|
||||
|| (property.DeclaringType.IsInterface && existingProperty.DeclaringType.ImplementInterface(property.DeclaringType)))
|
||||
{
|
||||
// current property is hidden by the existing so don't add it
|
||||
return;
|
||||
|
||||
@@ -665,6 +665,21 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
int end = start + length;
|
||||
|
||||
// Int32.MaxValue and MinValue are 10 chars
|
||||
if (length > 10)
|
||||
{
|
||||
// invalid result takes precedence over overflow
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
int c = chars[i] - '0';
|
||||
|
||||
if (c < 0 || c > 9)
|
||||
return ParseResult.Invalid;
|
||||
}
|
||||
|
||||
return ParseResult.Overflow;
|
||||
}
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
int c = chars[i] - '0';
|
||||
@@ -730,6 +745,21 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
int end = start + length;
|
||||
|
||||
// Int64.MaxValue and MinValue are 19 chars
|
||||
if (length > 19)
|
||||
{
|
||||
// invalid result takes precedence over overflow
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
int c = chars[i] - '0';
|
||||
|
||||
if (c < 0 || c > 9)
|
||||
return ParseResult.Invalid;
|
||||
}
|
||||
|
||||
return ParseResult.Overflow;
|
||||
}
|
||||
|
||||
for (int i = start; i < end; i++)
|
||||
{
|
||||
int c = chars[i] - '0';
|
||||
|
||||
@@ -550,5 +550,23 @@ namespace Newtonsoft.Json.Utilities
|
||||
Type match;
|
||||
return type.AssignableToTypeName(fullTypeName, out match);
|
||||
}
|
||||
|
||||
public static bool ImplementInterface(this Type type, Type interfaceType)
|
||||
{
|
||||
for (Type currentType = type; currentType != null; currentType = currentType.BaseType)
|
||||
{
|
||||
Type[] interfaces = currentType.GetInterfaces();
|
||||
|
||||
for (int i = 0; i < interfaces.Length; i++)
|
||||
{
|
||||
if (interfaces[i] == interfaceType || (interfaces[i] != null && interfaces[i].ImplementInterface(interfaceType)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user