Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Newtonsoft.Json.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Newton-King <james@newtonking.com>2012-03-10 08:39:39 +0400
committerJames Newton-King <james@newtonking.com>2012-03-10 08:39:39 +0400
commitf9e5745425f3d4e7ca4da340f583a45c7d495660 (patch)
treeccc91235725fc8eb337af5dd7b86ec39e3d05db6
parentd32061cd1659203acacb8bca9e08d15c70d7d3d8 (diff)
-Changed serializer to fallback to use a private default constructor
-Changed error message when deserializing a JSON object/array onto the wrong kind of type to be more descriptive
-rw-r--r--Doc/SerializationSettings.html13
-rw-r--r--Src/Newtonsoft.Json.Tests/PerformanceTests.cs15
-rw-r--r--Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs2
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs7
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs36
-rw-r--r--Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs10
-rw-r--r--Src/Newtonsoft.Json/ConstructorHandling.cs4
-rw-r--r--Src/Newtonsoft.Json/Properties/AssemblyInfo.cs2
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonContract.cs2
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs14
10 files changed, 71 insertions, 34 deletions
diff --git a/Doc/SerializationSettings.html b/Doc/SerializationSettings.html
index 21a51c2..d11a80f 100644
--- a/Doc/SerializationSettings.html
+++ b/Doc/SerializationSettings.html
@@ -405,10 +405,11 @@ DefaultValueHandling controls how Json.NET uses default values set using the .NE
<div class="summary">
By default Json.NET will first look for a constructor
marked with the JsonConstructorAttribute, then look for a public default
- constructor (a constructor that doesn't take any arguments) and finally check if
- the class has a single public constructor with arguments. If the class has
- multiple public constructors with arguments an error will be thrown. This can be
- fixed by marking one of the constructors with the JsonConstructorAttribute.
+ constructor (a constructor that doesn't take any arguments), then check if
+ the class has a single public constructor with arguments and finally check
+ for a non-public default constructor. If the class has multiple public
+ constructors with arguments an error will be thrown. This can be fixed by
+ marking one of the constructors with the JsonConstructorAttribute.
</div>
<br>
</td>
@@ -419,8 +420,8 @@ DefaultValueHandling controls how Json.NET uses default values set using the .NE
</td>
<td>
<div class="summary">
- Json.NET will fallback to
- using a classes private default constructor if available.
+ Json.NET will use a classes private default constructor before constructors
+ with arguments if available.
</div>
<br>
</td>
diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
index 7d3b8bd..268fe13 100644
--- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
+++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
@@ -704,21 +704,6 @@ namespace Newtonsoft.Json.Tests
}
[Test]
- public void RecursiveLoop()
- {
- JArray a1 = new JArray();
- JArray a2 = new JArray();
- JArray a3 = new JArray();
- JArray a4 = new JArray();
-
- a1.Add(a2);
- a2.Add(a3);
- a3.Add(a4);
-
-
- }
-
- [Test]
public void NestedJToken()
{
Stopwatch sw;
diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs
index 7920d37..1646871 100644
--- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs
+++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs
@@ -72,5 +72,5 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.0.8.0")]
#if !PocketPC
-[assembly: AssemblyFileVersion("4.0.8.14707")]
+[assembly: AssemblyFileVersion("4.0.8.14710")]
#endif
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs
index 1f8ade6..1d48a81 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/ConstructorHandlingTests.cs
@@ -7,12 +7,13 @@ namespace Newtonsoft.Json.Tests.Serialization
public class ConstructorHandlingTests : TestFixtureBase
{
[Test]
- [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = "Unable to find a constructor to use for type Newtonsoft.Json.Tests.TestObjects.PrivateConstructorTestClass. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Line 1, position 6.")]
- public void FailWithPrivateConstructorAndDefault()
+ public void UsePrivateConstructorIfThereAreMultipleConstructorsWithParametersAndNothingToFallbackTo()
{
string json = @"{Name:""Name!""}";
- JsonConvert.DeserializeObject<PrivateConstructorTestClass>(json);
+ var c = JsonConvert.DeserializeObject<PrivateConstructorTestClass>(json);
+
+ Assert.AreEqual("Name!", c.Name);
}
[Test]
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
index d568eec..0f7f7ff 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
@@ -1905,7 +1905,9 @@ keyword such as type of business.""
}
[Test]
- [ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Cannot deserialize JSON array into type 'Newtonsoft.Json.Tests.TestObjects.Person'. Line 1, position 1.")]
+ [ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Cannot deserialize JSON array (i.e. [1,2,3]) into type 'Newtonsoft.Json.Tests.TestObjects.Person'.
+The deserialized type must be an array or implement a collection interface like IEnumerable, ICollection or IList.
+To force JSON arrays to deserialize add the JsonArrayAttribute to the type. Line 1, position 1.")]
public void CannotDeserializeArrayIntoObject()
{
string json = @"[]";
@@ -1914,7 +1916,9 @@ keyword such as type of business.""
}
[Test]
- [ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Cannot deserialize JSON object into type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'. Line 1, position 2.")]
+ [ExpectedException(typeof (JsonSerializationException), ExpectedMessage = @"Cannot deserialize JSON object (i.e. {""name"":""value""}) into type 'System.Collections.Generic.List`1[Newtonsoft.Json.Tests.TestObjects.Person]'.
+The deserialized type should be a normal .NET type (i.e. not a primitive type like integer, not a collection type like an array or List<T>) or a dictionary type (i.e. Dictionary<TKey, TValue>).
+To force JSON objects to deserialize add the JsonObjectAttribute to the type. Line 1, position 2.")]
public void CannotDeserializeObjectIntoArray()
{
string json = @"{}";
@@ -5550,9 +5554,37 @@ Parameter name: value")]
Assert.AreEqual("Pre", c2.PreField);
Assert.AreEqual("Post", c2.PostField);
}
+
+ [Test]
+ public void PrivateConstructor()
+ {
+ var person = PersonWithPrivateConstructor.CreatePerson();
+ person.Name = "John Doe";
+ person.Age = 25;
+
+ var serializedPerson = JsonConvert.SerializeObject(person);
+ var roundtrippedPerson = JsonConvert.DeserializeObject<PersonWithPrivateConstructor>(serializedPerson);
+
+ Assert.AreEqual(person.Name, roundtrippedPerson.Name);
+ }
#endif
}
+ public class PersonWithPrivateConstructor
+ {
+ private PersonWithPrivateConstructor()
+ { }
+
+ public static PersonWithPrivateConstructor CreatePerson()
+ {
+ return new PersonWithPrivateConstructor();
+ }
+
+ public string Name { get; set; }
+
+ public int Age { get; set; }
+ }
+
public class DateTimeWrapper
{
public DateTime Value { get; set; }
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs
index ad52d17..698406d 100644
--- a/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/PrivateConstructorTestClass.cs
@@ -33,5 +33,15 @@ namespace Newtonsoft.Json.Tests.TestObjects
private PrivateConstructorTestClass()
{
}
+
+ // multiple constructors with arguments so the serializer doesn't know what to fall back to
+ private PrivateConstructorTestClass(object a)
+ {
+ }
+
+ // multiple constructors with arguments so the serializer doesn't know what to fall back to
+ private PrivateConstructorTestClass(object a, object b)
+ {
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/ConstructorHandling.cs b/Src/Newtonsoft.Json/ConstructorHandling.cs
index 591d150..123977b 100644
--- a/Src/Newtonsoft.Json/ConstructorHandling.cs
+++ b/Src/Newtonsoft.Json/ConstructorHandling.cs
@@ -36,11 +36,11 @@ namespace Newtonsoft.Json
public enum ConstructorHandling
{
/// <summary>
- /// First attempt to use the public default constructor then fall back to single paramatized constructor.
+ /// First attempt to use the public default constructor, then fall back to single paramatized constructor, then the non-public default constructor.
/// </summary>
Default = 0,
/// <summary>
- /// Allow Json.NET to use a non-public default constructor.
+ /// Json.NET will use a non-public default constructor before falling back to a paramatized constructor.
/// </summary>
AllowNonPublicDefaultConstructor = 1
}
diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
index 73df4a0..4f81f4d 100644
--- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
+++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs
@@ -85,7 +85,7 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.0.8.0")]
#if !PocketPC
-[assembly: AssemblyFileVersion("4.0.8.14707")]
+[assembly: AssemblyFileVersion("4.0.8.14710")]
#endif
[assembly: CLSCompliant(true)]
diff --git a/Src/Newtonsoft.Json/Serialization/JsonContract.cs b/Src/Newtonsoft.Json/Serialization/JsonContract.cs
index db38243..8a399a4 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonContract.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonContract.cs
@@ -119,7 +119,7 @@ namespace Newtonsoft.Json.Serialization
public Func<object> DefaultCreator { get; set; }
/// <summary>
- /// Gets or sets a value indicating whether [default creator non public].
+ /// Gets or sets a value indicating whether the default creator is non public.
/// </summary>
/// <value><c>true</c> if the default object creator is non-public; otherwise, <c>false</c>.</value>
public bool DefaultCreatorNonPublic { get; set; }
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
index 2a81a8a..7556323 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
@@ -468,7 +468,9 @@ namespace Newtonsoft.Json.Serialization
#endif
}
- throw CreateSerializationException(reader, "Cannot deserialize JSON object into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
+ throw CreateSerializationException(reader, @"Cannot deserialize JSON object (i.e. {{""name"":""value""}}) into type '{0}'.
+The deserialized type should be a normal .NET type (i.e. not a primitive type like integer, not a collection type like an array or List<T>) or a dictionary type (i.e. Dictionary<TKey, TValue>).
+To force JSON objects to deserialize add the JsonObjectAttribute to the type.".FormatWith(CultureInfo.InvariantCulture, objectType));
}
private JsonArrayContract EnsureArrayContract(JsonReader reader, Type objectType, JsonContract contract)
@@ -478,7 +480,9 @@ namespace Newtonsoft.Json.Serialization
JsonArrayContract arrayContract = contract as JsonArrayContract;
if (arrayContract == null)
- throw CreateSerializationException(reader, "Cannot deserialize JSON array into type '{0}'.".FormatWith(CultureInfo.InvariantCulture, objectType));
+ throw CreateSerializationException(reader, @"Cannot deserialize JSON array (i.e. [1,2,3]) into type '{0}'.
+The deserialized type must be an array or implement a collection interface like IEnumerable, ICollection or IList.
+To force JSON arrays to deserialize add the JsonArrayAttribute to the type.".FormatWith(CultureInfo.InvariantCulture, objectType));
return arrayContract;
}
@@ -954,8 +958,12 @@ namespace Newtonsoft.Json.Serialization
newObject = contract.OverrideConstructor.Invoke(null);
}
else if (contract.DefaultCreator != null &&
- (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
+ (!contract.DefaultCreatorNonPublic || Serializer.ConstructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || contract.ParametrizedConstructor == null))
{
+ // use the default constructor if it is...
+ // public
+ // non-public and the user has change constructor handling settings
+ // non-public and there is no other constructor
newObject = contract.DefaultCreator();
}
else if (contract.ParametrizedConstructor != null)