-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:
James Newton-King
2015-08-30 22:24:57 +12:00
parent 375ec02996
commit 85e7968ed9
9 changed files with 343 additions and 7 deletions
+5 -4
View File
@@ -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;
}
}
}