-Added JsonConstructorAttribute support for lists and dictionaries
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<topic id="QueryJsonSelectTokenEscaped" revisionNumber="1">
|
||||
<developerConceptualDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<introduction>
|
||||
<para>This sample loads JSON with properties that required escaped queries using <codeEntityReference>M:Newtonsoft.Json.Linq.JToken.SelectToken(System.String)</codeEntityReference>.</para>
|
||||
<para>This sample loads JSON with properties that need to be escaped when queried with <codeEntityReference>M:Newtonsoft.Json.Linq.JToken.SelectToken(System.String)</codeEntityReference>.</para>
|
||||
</introduction>
|
||||
<section>
|
||||
<title>Sample</title>
|
||||
|
||||
@@ -146,6 +146,7 @@
|
||||
<codeEntityReference>T:Newtonsoft.Json.JsonPropertyAttribute</codeEntityReference>
|
||||
<codeEntityReference>T:Newtonsoft.Json.JsonConverterAttribute</codeEntityReference>
|
||||
<codeEntityReference>T:Newtonsoft.Json.JsonExtensionDataAttribute</codeEntityReference>
|
||||
<codeEntityReference>T:Newtonsoft.Json.JsonConstructorAttribute</codeEntityReference>
|
||||
</relatedTopics>
|
||||
</developerConceptualDocument>
|
||||
</topic>
|
||||
@@ -203,7 +203,7 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
|
||||
Assert.IsFalse(contract.IsInstantiable);
|
||||
Assert.IsNull(contract.DefaultCreator);
|
||||
Assert.IsFalse(contract.HasParametrizedCreator);
|
||||
Assert.IsFalse(contract.HasParameterizedCreatorInternal);
|
||||
|
||||
ExceptionAssert.Throws<JsonSerializationException>(() => JsonConvert.DeserializeObject<AbstractListTestClass<int>>(@"[1,2]", new JsonSerializerSettings
|
||||
{
|
||||
@@ -283,7 +283,7 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
|
||||
Assert.IsFalse(contract.IsInstantiable);
|
||||
Assert.IsNull(contract.DefaultCreator);
|
||||
Assert.IsFalse(contract.HasParametrizedCreator);
|
||||
Assert.IsFalse(contract.HasParameterizedCreatorInternal);
|
||||
|
||||
ExceptionAssert.Throws<JsonSerializationException>(() => JsonConvert.DeserializeObject<AbstractDictionaryTestClass<string, int>>(@"{key1:1,key2:2}", new JsonSerializerSettings
|
||||
{
|
||||
@@ -436,13 +436,13 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ParametrizedCreator()
|
||||
public void ParameterizedCreator()
|
||||
{
|
||||
var resolver = new DefaultContractResolver();
|
||||
var contract = (JsonObjectContract)resolver.ResolveContract(typeof(PublicParametizedConstructorWithPropertyNameConflictWithAttribute));
|
||||
|
||||
Assert.IsNull(contract.DefaultCreator);
|
||||
Assert.IsNotNull(contract.ParametrizedCreator);
|
||||
Assert.IsNotNull(contract.ParameterizedCreator);
|
||||
#pragma warning disable 618
|
||||
Assert.AreEqual(contract.ParametrizedConstructor, typeof(PublicParametizedConstructorWithPropertyNameConflictWithAttribute).GetConstructor(new[] { typeof(string) }));
|
||||
#pragma warning restore 618
|
||||
@@ -452,7 +452,7 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
#pragma warning disable 618
|
||||
contract.ParametrizedConstructor = null;
|
||||
#pragma warning restore 618
|
||||
Assert.IsNull(contract.ParametrizedCreator);
|
||||
Assert.IsNull(contract.ParameterizedCreator);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -59,6 +59,248 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
[TestFixture]
|
||||
public class JsonSerializerCollectionsTests : TestFixtureBase
|
||||
{
|
||||
public class TestCollectionPrivateParameterized : IEnumerable<int>
|
||||
{
|
||||
private readonly List<int> _bars;
|
||||
|
||||
public TestCollectionPrivateParameterized()
|
||||
{
|
||||
_bars = new List<int>();
|
||||
}
|
||||
|
||||
[JsonConstructor]
|
||||
private TestCollectionPrivateParameterized(IEnumerable<int> bars)
|
||||
{
|
||||
_bars = new List<int>(bars);
|
||||
}
|
||||
|
||||
public void Add(int bar)
|
||||
{
|
||||
_bars.Add(bar);
|
||||
}
|
||||
|
||||
public IEnumerator<int> GetEnumerator() => _bars.GetEnumerator();
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CollectionJsonConstructorPrivateParameterized()
|
||||
{
|
||||
TestCollectionPrivateParameterized c1 = new TestCollectionPrivateParameterized();
|
||||
c1.Add(0);
|
||||
c1.Add(1);
|
||||
c1.Add(2);
|
||||
string json = JsonConvert.SerializeObject(c1);
|
||||
TestCollectionPrivateParameterized c2 = JsonConvert.DeserializeObject<TestCollectionPrivateParameterized>(json);
|
||||
|
||||
List<int> values = c2.ToList();
|
||||
|
||||
Assert.AreEqual(3, values.Count);
|
||||
Assert.AreEqual(0, values[0]);
|
||||
Assert.AreEqual(1, values[1]);
|
||||
Assert.AreEqual(2, values[2]);
|
||||
}
|
||||
|
||||
public class TestCollectionPrivate : List<int>
|
||||
{
|
||||
[JsonConstructor]
|
||||
private TestCollectionPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
public static TestCollectionPrivate Create()
|
||||
{
|
||||
return new TestCollectionPrivate();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CollectionJsonConstructorPrivate()
|
||||
{
|
||||
TestCollectionPrivate c1 = TestCollectionPrivate.Create();
|
||||
c1.Add(0);
|
||||
c1.Add(1);
|
||||
c1.Add(2);
|
||||
string json = JsonConvert.SerializeObject(c1);
|
||||
TestCollectionPrivate c2 = JsonConvert.DeserializeObject<TestCollectionPrivate>(json);
|
||||
|
||||
List<int> values = c2.ToList();
|
||||
|
||||
Assert.AreEqual(3, values.Count);
|
||||
Assert.AreEqual(0, values[0]);
|
||||
Assert.AreEqual(1, values[1]);
|
||||
Assert.AreEqual(2, values[2]);
|
||||
}
|
||||
|
||||
public class TestCollectionMultipleParameters : List<int>
|
||||
{
|
||||
[JsonConstructor]
|
||||
public TestCollectionMultipleParameters(string s1, string s2)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CollectionJsonConstructorMultipleParameters()
|
||||
{
|
||||
ExceptionAssert.Throws<JsonException>(
|
||||
() => JsonConvert.SerializeObject(new TestCollectionMultipleParameters(null, null)),
|
||||
"Constructor for 'Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+TestCollectionMultipleParameters' must have no parameters or a single parameter that implements 'System.Collections.Generic.IEnumerable`1[System.Int32]'.");
|
||||
}
|
||||
|
||||
public class TestCollectionBadIEnumerableParameter : List<int>
|
||||
{
|
||||
[JsonConstructor]
|
||||
public TestCollectionBadIEnumerableParameter(List<string> l)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CollectionJsonConstructorBadIEnumerableParameter()
|
||||
{
|
||||
ExceptionAssert.Throws<JsonException>(
|
||||
() => JsonConvert.SerializeObject(new TestCollectionBadIEnumerableParameter(null)),
|
||||
"Constructor for 'Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+TestCollectionBadIEnumerableParameter' must have no parameters or a single parameter that implements 'System.Collections.Generic.IEnumerable`1[System.Int32]'.");
|
||||
}
|
||||
|
||||
#if !(DNXCORE50 || PORTABLE)
|
||||
public class TestCollectionNonGeneric : ArrayList
|
||||
{
|
||||
[JsonConstructor]
|
||||
public TestCollectionNonGeneric(IEnumerable l)
|
||||
: base(l.Cast<object>().ToList())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CollectionJsonConstructorNonGeneric()
|
||||
{
|
||||
string json = @"[1,2,3]";
|
||||
TestCollectionNonGeneric l = JsonConvert.DeserializeObject<TestCollectionNonGeneric>(json);
|
||||
|
||||
Assert.AreEqual(3, l.Count);
|
||||
Assert.AreEqual(1, l[0]);
|
||||
Assert.AreEqual(2, l[1]);
|
||||
Assert.AreEqual(3, l[2]);
|
||||
}
|
||||
#endif
|
||||
|
||||
public class TestDictionaryPrivateParameterized : Dictionary<string, int>
|
||||
{
|
||||
public TestDictionaryPrivateParameterized()
|
||||
{
|
||||
}
|
||||
|
||||
[JsonConstructor]
|
||||
private TestDictionaryPrivateParameterized(IEnumerable<KeyValuePair<string, int>> bars)
|
||||
: base(bars.ToDictionary(k => k.Key, k => k.Value))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DictionaryJsonConstructorPrivateParameterized()
|
||||
{
|
||||
TestDictionaryPrivateParameterized c1 = new TestDictionaryPrivateParameterized();
|
||||
c1.Add("zero", 0);
|
||||
c1.Add("one", 1);
|
||||
c1.Add("two", 2);
|
||||
string json = JsonConvert.SerializeObject(c1);
|
||||
TestDictionaryPrivateParameterized c2 = JsonConvert.DeserializeObject<TestDictionaryPrivateParameterized>(json);
|
||||
|
||||
Assert.AreEqual(3, c2.Count);
|
||||
Assert.AreEqual(0, c2["zero"]);
|
||||
Assert.AreEqual(1, c2["one"]);
|
||||
Assert.AreEqual(2, c2["two"]);
|
||||
}
|
||||
|
||||
public class TestDictionaryPrivate : Dictionary<string, int>
|
||||
{
|
||||
[JsonConstructor]
|
||||
private TestDictionaryPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
public static TestDictionaryPrivate Create()
|
||||
{
|
||||
return new TestDictionaryPrivate();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DictionaryJsonConstructorPrivate()
|
||||
{
|
||||
TestDictionaryPrivate c1 = TestDictionaryPrivate.Create();
|
||||
c1.Add("zero", 0);
|
||||
c1.Add("one", 1);
|
||||
c1.Add("two", 2);
|
||||
string json = JsonConvert.SerializeObject(c1);
|
||||
TestDictionaryPrivate c2 = JsonConvert.DeserializeObject<TestDictionaryPrivate>(json);
|
||||
|
||||
Assert.AreEqual(3, c2.Count);
|
||||
Assert.AreEqual(0, c2["zero"]);
|
||||
Assert.AreEqual(1, c2["one"]);
|
||||
Assert.AreEqual(2, c2["two"]);
|
||||
}
|
||||
|
||||
public class TestDictionaryMultipleParameters : Dictionary<string, int>
|
||||
{
|
||||
[JsonConstructor]
|
||||
public TestDictionaryMultipleParameters(string s1, string s2)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DictionaryJsonConstructorMultipleParameters()
|
||||
{
|
||||
ExceptionAssert.Throws<JsonException>(
|
||||
() => JsonConvert.SerializeObject(new TestDictionaryMultipleParameters(null, null)),
|
||||
"Constructor for 'Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+TestDictionaryMultipleParameters' must have no parameters or a single parameter that implements 'System.Collections.Generic.IEnumerable`1[System.Collections.Generic.KeyValuePair`2[System.String,System.Int32]]'.");
|
||||
}
|
||||
|
||||
public class TestDictionaryBadIEnumerableParameter : Dictionary<string, int>
|
||||
{
|
||||
[JsonConstructor]
|
||||
public TestDictionaryBadIEnumerableParameter(Dictionary<string, string> l)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DictionaryJsonConstructorBadIEnumerableParameter()
|
||||
{
|
||||
ExceptionAssert.Throws<JsonException>(
|
||||
() => JsonConvert.SerializeObject(new TestDictionaryBadIEnumerableParameter(null)),
|
||||
"Constructor for 'Newtonsoft.Json.Tests.Serialization.JsonSerializerCollectionsTests+TestDictionaryBadIEnumerableParameter' must have no parameters or a single parameter that implements 'System.Collections.Generic.IEnumerable`1[System.Collections.Generic.KeyValuePair`2[System.String,System.Int32]]'.");
|
||||
}
|
||||
|
||||
#if !(DNXCORE50 || PORTABLE)
|
||||
public class TestDictionaryNonGeneric : Hashtable
|
||||
{
|
||||
[JsonConstructor]
|
||||
public TestDictionaryNonGeneric(IDictionary d)
|
||||
: base(d)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DictionaryJsonConstructorNonGeneric()
|
||||
{
|
||||
string json = @"{'zero':0,'one':1,'two':2}";
|
||||
TestDictionaryNonGeneric d = JsonConvert.DeserializeObject<TestDictionaryNonGeneric>(json);
|
||||
|
||||
Assert.AreEqual(3, d.Count);
|
||||
Assert.AreEqual(0, d["zero"]);
|
||||
Assert.AreEqual(1, d["one"]);
|
||||
Assert.AreEqual(2, d["two"]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !(NETFX_CORE || DNXCORE50)
|
||||
public class NameValueCollectionTestClass
|
||||
{
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
ConstructorInfo constructor = typeof(OutAndRefTestClass).GetConstructors().Single(c => c.GetParameters().Count() == 1);
|
||||
|
||||
var creator = DynamicReflectionDelegateFactory.Instance.CreateParametrizedConstructor(constructor);
|
||||
var creator = DynamicReflectionDelegateFactory.Instance.CreateParameterizedConstructor(constructor);
|
||||
|
||||
object[] args = new object[] { "Input" };
|
||||
OutAndRefTestClass o = (OutAndRefTestClass)creator(args);
|
||||
@@ -71,7 +71,7 @@ namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
ConstructorInfo constructor = typeof(OutAndRefTestClass).GetConstructors().Single(c => c.GetParameters().Count() == 2);
|
||||
|
||||
var creator = DynamicReflectionDelegateFactory.Instance.CreateParametrizedConstructor(constructor);
|
||||
var creator = DynamicReflectionDelegateFactory.Instance.CreateParameterizedConstructor(constructor);
|
||||
|
||||
object[] args = new object[] { "Input", false };
|
||||
OutAndRefTestClass o = (OutAndRefTestClass)creator(args);
|
||||
@@ -85,7 +85,7 @@ namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
ConstructorInfo constructor = typeof(OutAndRefTestClass).GetConstructors().Single(c => c.GetParameters().Count() == 3);
|
||||
|
||||
var creator = DynamicReflectionDelegateFactory.Instance.CreateParametrizedConstructor(constructor);
|
||||
var creator = DynamicReflectionDelegateFactory.Instance.CreateParameterizedConstructor(constructor);
|
||||
|
||||
object[] args = new object[] { "Input", true, null };
|
||||
OutAndRefTestClass o = (OutAndRefTestClass)creator(args);
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
ConstructorInfo constructor = TestReflectionUtils.GetConstructors(typeof(OutAndRefTestClass)).Single(c => c.GetParameters().Count() == 1);
|
||||
|
||||
var creator = ExpressionReflectionDelegateFactory.Instance.CreateParametrizedConstructor(constructor);
|
||||
var creator = ExpressionReflectionDelegateFactory.Instance.CreateParameterizedConstructor(constructor);
|
||||
|
||||
object[] args = new object[] { "Input" };
|
||||
OutAndRefTestClass o = (OutAndRefTestClass)creator(args);
|
||||
@@ -68,7 +68,7 @@ namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
ConstructorInfo constructor = TestReflectionUtils.GetConstructors(typeof(OutAndRefTestClass)).Single(c => c.GetParameters().Count() == 2);
|
||||
|
||||
var creator = ExpressionReflectionDelegateFactory.Instance.CreateParametrizedConstructor(constructor);
|
||||
var creator = ExpressionReflectionDelegateFactory.Instance.CreateParameterizedConstructor(constructor);
|
||||
|
||||
object[] args = new object[] { "Input", null };
|
||||
OutAndRefTestClass o = (OutAndRefTestClass)creator(args);
|
||||
@@ -81,7 +81,7 @@ namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
ConstructorInfo constructor = TestReflectionUtils.GetConstructors(typeof(OutAndRefTestClass)).Single(c => c.GetParameters().Count() == 3);
|
||||
|
||||
var creator = ExpressionReflectionDelegateFactory.Instance.CreateParametrizedConstructor(constructor);
|
||||
var creator = ExpressionReflectionDelegateFactory.Instance.CreateParameterizedConstructor(constructor);
|
||||
|
||||
object[] args = new object[] { "Input", true, null };
|
||||
OutAndRefTestClass o = (OutAndRefTestClass)creator(args);
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
ConstructorInfo constructor = TestReflectionUtils.GetConstructors(typeof(OutAndRefTestClass)).Single(c => c.GetParameters().Count() == 1);
|
||||
|
||||
var creator = LateBoundReflectionDelegateFactory.Instance.CreateParametrizedConstructor(constructor);
|
||||
var creator = LateBoundReflectionDelegateFactory.Instance.CreateParameterizedConstructor(constructor);
|
||||
|
||||
object[] args = new object[] { "Input" };
|
||||
OutAndRefTestClass o = (OutAndRefTestClass)creator(args);
|
||||
@@ -67,7 +67,7 @@ namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
ConstructorInfo constructor = TestReflectionUtils.GetConstructors(typeof(OutAndRefTestClass)).Single(c => c.GetParameters().Count() == 2);
|
||||
|
||||
var creator = LateBoundReflectionDelegateFactory.Instance.CreateParametrizedConstructor(constructor);
|
||||
var creator = LateBoundReflectionDelegateFactory.Instance.CreateParameterizedConstructor(constructor);
|
||||
|
||||
object[] args = new object[] { "Input", null };
|
||||
OutAndRefTestClass o = (OutAndRefTestClass)creator(args);
|
||||
@@ -80,7 +80,7 @@ namespace Newtonsoft.Json.Tests.Utilities
|
||||
{
|
||||
ConstructorInfo constructor = TestReflectionUtils.GetConstructors(typeof(OutAndRefTestClass)).Single(c => c.GetParameters().Count() == 3);
|
||||
|
||||
var creator = LateBoundReflectionDelegateFactory.Instance.CreateParametrizedConstructor(constructor);
|
||||
var creator = LateBoundReflectionDelegateFactory.Instance.CreateParameterizedConstructor(constructor);
|
||||
|
||||
object[] args = new object[] { "Input", true, null };
|
||||
OutAndRefTestClass o = (OutAndRefTestClass)creator(args);
|
||||
|
||||
@@ -398,7 +398,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
}
|
||||
else if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic)
|
||||
{
|
||||
ConstructorInfo constructor = GetParametrizedConstructor(contract.NonNullableUnderlyingType);
|
||||
ConstructorInfo constructor = GetParameterizedConstructor(contract.NonNullableUnderlyingType);
|
||||
if (constructor != null)
|
||||
{
|
||||
#pragma warning disable 618
|
||||
@@ -511,7 +511,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
Type enumerableWrapper = typeof(DictionaryEnumerator<,>).MakeGenericType(keyType, valueType);
|
||||
ConstructorInfo constructors = enumerableWrapper.GetConstructors().First();
|
||||
ObjectConstructor<object> createEnumerableWrapper = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(constructors);
|
||||
ObjectConstructor<object> createEnumerableWrapper = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(constructors);
|
||||
|
||||
ExtensionDataGetter extensionDataGetter = o =>
|
||||
{
|
||||
@@ -591,7 +591,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
return null;
|
||||
}
|
||||
|
||||
private ConstructorInfo GetParametrizedConstructor(Type objectType)
|
||||
private ConstructorInfo GetParameterizedConstructor(Type objectType)
|
||||
{
|
||||
IList<ConstructorInfo> constructors = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).ToList();
|
||||
|
||||
@@ -878,6 +878,31 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
contract.DictionaryKeyResolver = ResolveDictionaryKey;
|
||||
|
||||
ConstructorInfo overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
|
||||
|
||||
if (overrideConstructor != null)
|
||||
{
|
||||
ParameterInfo[] parameters = overrideConstructor.GetParameters();
|
||||
Type expectedParameterType = (contract.DictionaryKeyType != null && contract.DictionaryValueType != null)
|
||||
? typeof(IEnumerable<>).MakeGenericType(typeof(KeyValuePair<,>).MakeGenericType(contract.DictionaryKeyType, contract.DictionaryValueType))
|
||||
: typeof(IDictionary);
|
||||
|
||||
if (parameters.Length == 0)
|
||||
{
|
||||
contract.HasParameterizedCreator = false;
|
||||
}
|
||||
else if (parameters.Length == 1 && expectedParameterType.IsAssignableFrom(parameters[0].ParameterType))
|
||||
{
|
||||
contract.HasParameterizedCreator = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonException("Constructor for '{0}' must have no parameters or a single parameter that implements '{1}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType, expectedParameterType));
|
||||
}
|
||||
|
||||
contract.OverrideCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(overrideConstructor);
|
||||
}
|
||||
|
||||
return contract;
|
||||
}
|
||||
|
||||
@@ -891,6 +916,31 @@ namespace Newtonsoft.Json.Serialization
|
||||
JsonArrayContract contract = new JsonArrayContract(objectType);
|
||||
InitializeContract(contract);
|
||||
|
||||
ConstructorInfo overrideConstructor = GetAttributeConstructor(contract.NonNullableUnderlyingType);
|
||||
|
||||
if (overrideConstructor != null)
|
||||
{
|
||||
ParameterInfo[] parameters = overrideConstructor.GetParameters();
|
||||
Type expectedParameterType = (contract.CollectionItemType != null)
|
||||
? typeof(IEnumerable<>).MakeGenericType(contract.CollectionItemType)
|
||||
: typeof(IEnumerable);
|
||||
|
||||
if (parameters.Length == 0)
|
||||
{
|
||||
contract.HasParameterizedCreator = false;
|
||||
}
|
||||
else if (parameters.Length == 1 && expectedParameterType.IsAssignableFrom(parameters[0].ParameterType))
|
||||
{
|
||||
contract.HasParameterizedCreator = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonException("Constructor for '{0}' must have no parameters or a single parameter that implements '{1}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType, expectedParameterType));
|
||||
}
|
||||
|
||||
contract.OverrideCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(overrideConstructor);
|
||||
}
|
||||
|
||||
return contract;
|
||||
}
|
||||
|
||||
@@ -934,7 +984,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
ConstructorInfo constructorInfo = contract.NonNullableUnderlyingType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null);
|
||||
if (constructorInfo != null)
|
||||
{
|
||||
ObjectConstructor<object> creator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(constructorInfo);
|
||||
ObjectConstructor<object> creator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(constructorInfo);
|
||||
|
||||
contract.ISerializableCreator = creator;
|
||||
}
|
||||
|
||||
@@ -67,23 +67,46 @@ namespace Newtonsoft.Json.Serialization
|
||||
internal bool ShouldCreateWrapper { get; private set; }
|
||||
internal bool CanDeserialize { get; private set; }
|
||||
|
||||
private readonly ConstructorInfo _parametrizedConstructor;
|
||||
private readonly ConstructorInfo _parameterizedConstructor;
|
||||
|
||||
private ObjectConstructor<object> _parametrizedCreator;
|
||||
internal ObjectConstructor<object> ParametrizedCreator
|
||||
private ObjectConstructor<object> _parameterizedCreator;
|
||||
private ObjectConstructor<object> _overrideCreator;
|
||||
|
||||
internal ObjectConstructor<object> ParameterizedCreator
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_parametrizedCreator == null)
|
||||
_parametrizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(_parametrizedConstructor);
|
||||
if (_parameterizedCreator == null)
|
||||
_parameterizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(_parameterizedConstructor);
|
||||
|
||||
return _parametrizedCreator;
|
||||
return _parameterizedCreator;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasParametrizedCreator
|
||||
/// <summary>
|
||||
/// Gets or sets the function used to create the object. When set this function will override <see cref="JsonContract.DefaultCreator"/>.
|
||||
/// </summary>
|
||||
/// <value>The function used to create the object.</value>
|
||||
public ObjectConstructor<object> OverrideCreator
|
||||
{
|
||||
get { return _parametrizedCreator != null || _parametrizedConstructor != null; }
|
||||
get { return _overrideCreator; }
|
||||
set
|
||||
{
|
||||
_overrideCreator = value;
|
||||
// hacky
|
||||
CanDeserialize = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the creator has a parameter with the collection values.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if the creator has a parameter with the collection values; otherwise, <c>false</c>.</value>
|
||||
public bool HasParameterizedCreator { get; set; }
|
||||
|
||||
internal bool HasParameterizedCreatorInternal
|
||||
{
|
||||
get { return (HasParameterizedCreator || _parameterizedCreator != null || _parameterizedConstructor != null); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -119,7 +142,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
CreatedType = typeof(List<object>);
|
||||
|
||||
if (CollectionItemType != null)
|
||||
_parametrizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType);
|
||||
_parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType);
|
||||
|
||||
IsReadOnlyOrFixedSize = ReflectionUtils.InheritsGenericDefinition(underlyingType, typeof(ReadOnlyCollection<>));
|
||||
canDeserialize = true;
|
||||
@@ -137,7 +160,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
CreatedType = typeof(HashSet<>).MakeGenericType(CollectionItemType);
|
||||
#endif
|
||||
|
||||
_parametrizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType);
|
||||
_parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType);
|
||||
canDeserialize = true;
|
||||
ShouldCreateWrapper = true;
|
||||
}
|
||||
@@ -151,9 +174,9 @@ namespace Newtonsoft.Json.Serialization
|
||||
CreatedType = typeof(ReadOnlyCollection<>).MakeGenericType(CollectionItemType);
|
||||
|
||||
_genericCollectionDefinitionType = typeof(List<>).MakeGenericType(CollectionItemType);
|
||||
_parametrizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(CreatedType, CollectionItemType);
|
||||
_parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(CreatedType, CollectionItemType);
|
||||
IsReadOnlyOrFixedSize = true;
|
||||
canDeserialize = HasParametrizedCreator;
|
||||
canDeserialize = HasParameterizedCreatorInternal;
|
||||
}
|
||||
#endif
|
||||
else if (ReflectionUtils.ImplementsGenericDefinition(underlyingType, typeof(IEnumerable<>), out tempCollectionType))
|
||||
@@ -163,13 +186,13 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (ReflectionUtils.IsGenericDefinition(UnderlyingType, typeof(IEnumerable<>)))
|
||||
CreatedType = typeof(List<>).MakeGenericType(CollectionItemType);
|
||||
|
||||
_parametrizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType);
|
||||
_parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(underlyingType, CollectionItemType);
|
||||
|
||||
#if !(NET35 || NET20)
|
||||
if (!HasParametrizedCreator && underlyingType.Name == FSharpUtils.FSharpListTypeName)
|
||||
if (!HasParameterizedCreatorInternal && underlyingType.Name == FSharpUtils.FSharpListTypeName)
|
||||
{
|
||||
FSharpUtils.EnsureInitialized(underlyingType.Assembly());
|
||||
_parametrizedCreator = FSharpUtils.CreateSeq(CollectionItemType);
|
||||
_parameterizedCreator = FSharpUtils.CreateSeq(CollectionItemType);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -187,7 +210,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
IsReadOnlyOrFixedSize = true;
|
||||
ShouldCreateWrapper = true;
|
||||
canDeserialize = HasParametrizedCreator;
|
||||
canDeserialize = HasParameterizedCreatorInternal;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -218,7 +241,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (ImmutableCollectionsUtils.TryBuildImmutableForArrayContract(underlyingType, CollectionItemType, out immutableCreatedType, out immutableParameterizedCreator))
|
||||
{
|
||||
CreatedType = immutableCreatedType;
|
||||
_parametrizedCreator = immutableParameterizedCreator;
|
||||
_parameterizedCreator = immutableParameterizedCreator;
|
||||
IsReadOnlyOrFixedSize = true;
|
||||
CanDeserialize = true;
|
||||
}
|
||||
@@ -240,7 +263,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
constructorArgument = _genericCollectionDefinitionType;
|
||||
|
||||
ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { constructorArgument });
|
||||
_genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(genericWrapperConstructor);
|
||||
_genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(genericWrapperConstructor);
|
||||
}
|
||||
|
||||
return (IWrappedCollection)_genericWrapperCreator(list);
|
||||
@@ -251,7 +274,10 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (_genericTemporaryCollectionCreator == null)
|
||||
{
|
||||
// multidimensional array will also have array instances in it
|
||||
Type collectionItemType = (IsMultidimensionalArray) ? typeof(object) : CollectionItemType;
|
||||
Type collectionItemType = (IsMultidimensionalArray || CollectionItemType == null)
|
||||
? typeof(object)
|
||||
: CollectionItemType;
|
||||
|
||||
Type temporaryListType = typeof(List<>).MakeGenericType(collectionItemType);
|
||||
_genericTemporaryCollectionCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor<object>(temporaryListType);
|
||||
}
|
||||
|
||||
@@ -105,8 +105,11 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (jsonContainerAttribute != null)
|
||||
{
|
||||
if (jsonContainerAttribute.ItemConverterType != null)
|
||||
ItemConverter = JsonTypeReflector.CreateJsonConverterInstance(jsonContainerAttribute.ItemConverterType,
|
||||
jsonContainerAttribute.ItemConverterParameters);
|
||||
{
|
||||
ItemConverter = JsonTypeReflector.CreateJsonConverterInstance(
|
||||
jsonContainerAttribute.ItemConverterType,
|
||||
jsonContainerAttribute.ItemConverterParameters);
|
||||
}
|
||||
|
||||
ItemIsReference = jsonContainerAttribute._itemIsReference;
|
||||
ItemReferenceLoopHandling = jsonContainerAttribute._itemReferenceLoopHandling;
|
||||
|
||||
@@ -81,23 +81,41 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
internal bool ShouldCreateWrapper { get; private set; }
|
||||
|
||||
private readonly ConstructorInfo _parametrizedConstructor;
|
||||
private readonly ConstructorInfo _parameterizedConstructor;
|
||||
|
||||
private ObjectConstructor<object> _parametrizedCreator;
|
||||
internal ObjectConstructor<object> ParametrizedCreator
|
||||
private ObjectConstructor<object> _overrideCreator;
|
||||
private ObjectConstructor<object> _parameterizedCreator;
|
||||
|
||||
internal ObjectConstructor<object> ParameterizedCreator
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_parametrizedCreator == null)
|
||||
_parametrizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(_parametrizedConstructor);
|
||||
if (_parameterizedCreator == null)
|
||||
_parameterizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(_parameterizedConstructor);
|
||||
|
||||
return _parametrizedCreator;
|
||||
return _parameterizedCreator;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool HasParametrizedCreator
|
||||
/// <summary>
|
||||
/// Gets or sets the function used to create the object. When set this function will override <see cref="JsonContract.DefaultCreator"/>.
|
||||
/// </summary>
|
||||
/// <value>The function used to create the object.</value>
|
||||
public ObjectConstructor<object> OverrideCreator
|
||||
{
|
||||
get { return _parametrizedCreator != null || _parametrizedConstructor != null; }
|
||||
get { return _overrideCreator; }
|
||||
set { _overrideCreator = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the creator has a parameter with the dictionary values.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if the creator has a parameter with the dictionary values; otherwise, <c>false</c>.</value>
|
||||
public bool HasParameterizedCreator { get; set; }
|
||||
|
||||
internal bool HasParameterizedCreatorInternal
|
||||
{
|
||||
get { return (HasParameterizedCreator || _parameterizedCreator != null || _parameterizedConstructor != null); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -146,13 +164,13 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
if (keyType != null && valueType != null)
|
||||
{
|
||||
_parametrizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(CreatedType, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType));
|
||||
_parameterizedConstructor = CollectionUtils.ResolveEnumerableCollectionConstructor(CreatedType, typeof(KeyValuePair<,>).MakeGenericType(keyType, valueType));
|
||||
|
||||
#if !(NET35 || NET20)
|
||||
if (!HasParametrizedCreator && underlyingType.Name == FSharpUtils.FSharpMapTypeName)
|
||||
if (!HasParameterizedCreatorInternal && underlyingType.Name == FSharpUtils.FSharpMapTypeName)
|
||||
{
|
||||
FSharpUtils.EnsureInitialized(underlyingType.Assembly());
|
||||
_parametrizedCreator = FSharpUtils.CreateMap(keyType, valueType);
|
||||
_parameterizedCreator = FSharpUtils.CreateMap(keyType, valueType);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -182,7 +200,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (ImmutableCollectionsUtils.TryBuildImmutableForDictionaryContract(underlyingType, DictionaryKeyType, DictionaryValueType, out immutableCreatedType, out immutableParameterizedCreator))
|
||||
{
|
||||
CreatedType = immutableCreatedType;
|
||||
_parametrizedCreator = immutableParameterizedCreator;
|
||||
_parameterizedCreator = immutableParameterizedCreator;
|
||||
IsReadOnlyOrFixedSize = true;
|
||||
}
|
||||
#endif
|
||||
@@ -195,7 +213,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
_genericWrapperType = typeof(DictionaryWrapper<,>).MakeGenericType(DictionaryKeyType, DictionaryValueType);
|
||||
|
||||
ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType });
|
||||
_genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(genericWrapperConstructor);
|
||||
_genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(genericWrapperConstructor);
|
||||
}
|
||||
|
||||
return (IWrappedDictionary)_genericWrapperCreator(dictionary);
|
||||
@@ -205,7 +223,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
if (_genericTemporaryDictionaryCreator == null)
|
||||
{
|
||||
Type temporaryDictionaryType = typeof(Dictionary<,>).MakeGenericType(DictionaryKeyType, DictionaryValueType);
|
||||
Type temporaryDictionaryType = typeof(Dictionary<,>).MakeGenericType(DictionaryKeyType ?? typeof(object), DictionaryValueType ?? typeof(object));
|
||||
|
||||
_genericTemporaryDictionaryCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateDefaultConstructor<object>(temporaryDictionaryType);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,18 @@ namespace Newtonsoft.Json.Serialization
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="JsonProperty"/> instances that define the parameters used with <see cref="OverrideCreator"/>.
|
||||
/// </summary>
|
||||
public JsonPropertyCollection CreatorParameters { get; private set; }
|
||||
public JsonPropertyCollection CreatorParameters
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_creatorParameters == null)
|
||||
{
|
||||
_creatorParameters = new JsonPropertyCollection(UnderlyingType);
|
||||
}
|
||||
|
||||
return _creatorParameters;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the override constructor used to create the object.
|
||||
@@ -84,7 +95,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
set
|
||||
{
|
||||
_overrideConstructor = value;
|
||||
_overrideCreator = (value != null) ? JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(value) : null;
|
||||
_overrideCreator = (value != null) ? JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(value) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +110,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
set
|
||||
{
|
||||
_parametrizedConstructor = value;
|
||||
_parametrizedCreator = (value != null) ? JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(value) : null;
|
||||
_parameterizedCreator = (value != null) ? JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(value) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,9 +129,9 @@ namespace Newtonsoft.Json.Serialization
|
||||
}
|
||||
}
|
||||
|
||||
internal ObjectConstructor<object> ParametrizedCreator
|
||||
internal ObjectConstructor<object> ParameterizedCreator
|
||||
{
|
||||
get { return _parametrizedCreator; }
|
||||
get { return _parameterizedCreator; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -137,7 +148,8 @@ namespace Newtonsoft.Json.Serialization
|
||||
private ConstructorInfo _parametrizedConstructor;
|
||||
private ConstructorInfo _overrideConstructor;
|
||||
private ObjectConstructor<object> _overrideCreator;
|
||||
private ObjectConstructor<object> _parametrizedCreator;
|
||||
private ObjectConstructor<object> _parameterizedCreator;
|
||||
private JsonPropertyCollection _creatorParameters;
|
||||
|
||||
internal bool HasRequiredOrDefaultValueProperties
|
||||
{
|
||||
@@ -178,7 +190,6 @@ namespace Newtonsoft.Json.Serialization
|
||||
ContractType = JsonContractType.Object;
|
||||
|
||||
Properties = new JsonPropertyCollection(UnderlyingType);
|
||||
CreatorParameters = new JsonPropertyCollection(UnderlyingType);
|
||||
}
|
||||
|
||||
#if !(DOTNET || PORTABLE40 || PORTABLE)
|
||||
|
||||
@@ -484,7 +484,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (contract.OnErrorCallbacks.Count > 0)
|
||||
throw JsonSerializationException.Create(reader, "Cannot call OnError on readonly list, or dictionary created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
|
||||
|
||||
if (!dictionaryContract.HasParametrizedCreator)
|
||||
if (!dictionaryContract.HasParameterizedCreatorInternal)
|
||||
throw JsonSerializationException.Create(reader, "Cannot deserialize readonly or fixed size dictionary: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
|
||||
}
|
||||
|
||||
@@ -492,7 +492,9 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
if (createdFromNonDefaultCreator)
|
||||
{
|
||||
return dictionaryContract.ParametrizedCreator(dictionary);
|
||||
ObjectConstructor<object> creator = dictionaryContract.OverrideCreator ?? dictionaryContract.ParameterizedCreator;
|
||||
|
||||
return creator(dictionary);
|
||||
}
|
||||
else if (dictionary is IWrappedDictionary)
|
||||
{
|
||||
@@ -786,14 +788,18 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (contract.OnErrorCallbacks.Count > 0)
|
||||
throw JsonSerializationException.Create(reader, "Cannot call OnError on an array or readonly list, or list created from a non-default constructor: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
|
||||
|
||||
if (!arrayContract.HasParametrizedCreator && !arrayContract.IsArray)
|
||||
if (!arrayContract.HasParameterizedCreatorInternal && !arrayContract.IsArray)
|
||||
throw JsonSerializationException.Create(reader, "Cannot deserialize readonly or fixed size list: {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
|
||||
}
|
||||
|
||||
if (!arrayContract.IsMultidimensionalArray)
|
||||
{
|
||||
PopulateList(list, reader, arrayContract, member, id);
|
||||
}
|
||||
else
|
||||
{
|
||||
PopulateMultidimensionalArray(list, reader, arrayContract, member, id);
|
||||
}
|
||||
|
||||
if (createdFromNonDefaultCreator)
|
||||
{
|
||||
@@ -809,8 +815,9 @@ namespace Newtonsoft.Json.Serialization
|
||||
}
|
||||
else
|
||||
{
|
||||
// call constructor that takes IEnumerable<T>
|
||||
return arrayContract.ParametrizedCreator(list);
|
||||
ObjectConstructor<object> creator = arrayContract.OverrideCreator ?? arrayContract.ParameterizedCreator;
|
||||
|
||||
return creator(list);
|
||||
}
|
||||
}
|
||||
else if (list is IWrappedCollection)
|
||||
@@ -823,7 +830,9 @@ namespace Newtonsoft.Json.Serialization
|
||||
else
|
||||
{
|
||||
if (!arrayContract.CanDeserialize)
|
||||
{
|
||||
throw JsonSerializationException.Create(reader, "Cannot populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType));
|
||||
}
|
||||
|
||||
value = PopulateList((arrayContract.ShouldCreateWrapper) ? arrayContract.CreateWrapper(existingValue) : (IList)existingValue, reader, arrayContract, member, id);
|
||||
}
|
||||
@@ -1037,15 +1046,32 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
// some types like non-generic IEnumerable can be serialized but not deserialized
|
||||
if (!contract.CanDeserialize)
|
||||
{
|
||||
throw JsonSerializationException.Create(reader, "Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType));
|
||||
}
|
||||
|
||||
if (contract.IsReadOnlyOrFixedSize)
|
||||
if (contract.OverrideCreator != null)
|
||||
{
|
||||
if (contract.HasParameterizedCreator)
|
||||
{
|
||||
createdFromNonDefaultCreator = true;
|
||||
return contract.CreateTemporaryCollection();
|
||||
}
|
||||
else
|
||||
{
|
||||
createdFromNonDefaultCreator = false;
|
||||
return (IList)contract.OverrideCreator();
|
||||
}
|
||||
}
|
||||
else if (contract.IsReadOnlyOrFixedSize)
|
||||
{
|
||||
createdFromNonDefaultCreator = true;
|
||||
IList list = contract.CreateTemporaryCollection();
|
||||
|
||||
if (contract.ShouldCreateWrapper)
|
||||
{
|
||||
list = contract.CreateWrapper(list);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
@@ -1054,12 +1080,14 @@ namespace Newtonsoft.Json.Serialization
|
||||
object list = contract.DefaultCreator();
|
||||
|
||||
if (contract.ShouldCreateWrapper)
|
||||
{
|
||||
list = contract.CreateWrapper(list);
|
||||
}
|
||||
|
||||
createdFromNonDefaultCreator = false;
|
||||
return (IList)list;
|
||||
}
|
||||
else if (contract.HasParametrizedCreator)
|
||||
else if (contract.HasParameterizedCreatorInternal)
|
||||
{
|
||||
createdFromNonDefaultCreator = true;
|
||||
return contract.CreateTemporaryCollection();
|
||||
@@ -1075,7 +1103,20 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
private IDictionary CreateNewDictionary(JsonReader reader, JsonDictionaryContract contract, out bool createdFromNonDefaultCreator)
|
||||
{
|
||||
if (contract.IsReadOnlyOrFixedSize)
|
||||
if (contract.OverrideCreator != null)
|
||||
{
|
||||
if (contract.HasParameterizedCreator)
|
||||
{
|
||||
createdFromNonDefaultCreator = true;
|
||||
return contract.CreateTemporaryDictionary();
|
||||
}
|
||||
else
|
||||
{
|
||||
createdFromNonDefaultCreator = false;
|
||||
return (IDictionary)contract.OverrideCreator();
|
||||
}
|
||||
}
|
||||
else if (contract.IsReadOnlyOrFixedSize)
|
||||
{
|
||||
createdFromNonDefaultCreator = true;
|
||||
return contract.CreateTemporaryDictionary();
|
||||
@@ -1090,7 +1131,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
createdFromNonDefaultCreator = false;
|
||||
return (IDictionary)dictionary;
|
||||
}
|
||||
else if (contract.HasParametrizedCreator)
|
||||
else if (contract.HasParameterizedCreatorInternal)
|
||||
{
|
||||
createdFromNonDefaultCreator = true;
|
||||
return contract.CreateTemporaryDictionary();
|
||||
@@ -1937,7 +1978,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
newObject = objectContract.OverrideCreator(new object[0]);
|
||||
}
|
||||
else if (objectContract.DefaultCreator != null &&
|
||||
(!objectContract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParametrizedCreator == null))
|
||||
(!objectContract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor || objectContract.ParameterizedCreator == null))
|
||||
{
|
||||
// use the default constructor if it is...
|
||||
// public
|
||||
@@ -1945,10 +1986,10 @@ namespace Newtonsoft.Json.Serialization
|
||||
// non-public and there is no other creator
|
||||
newObject = objectContract.DefaultCreator();
|
||||
}
|
||||
else if (objectContract.ParametrizedCreator != null)
|
||||
else if (objectContract.ParameterizedCreator != null)
|
||||
{
|
||||
createdFromNonDefaultCreator = true;
|
||||
return CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.ParametrizedCreator, id);
|
||||
return CreateObjectUsingCreatorWithParameters(reader, objectContract, containerMember, objectContract.ParameterizedCreator, id);
|
||||
}
|
||||
|
||||
if (newObject == null)
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
if (null != parameterizedConstructorInfo)
|
||||
{
|
||||
parameterizedConstructor = ReflectionDelegateFactory.CreateParametrizedConstructor(parameterizedConstructorInfo);
|
||||
parameterizedConstructor = ReflectionDelegateFactory.CreateParameterizedConstructor(parameterizedConstructorInfo);
|
||||
return (JsonConverter)parameterizedConstructor(parameters);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -124,7 +124,9 @@ namespace Newtonsoft.Json.Utilities
|
||||
if (match == null)
|
||||
{
|
||||
if (genericEnumerable.IsAssignableFrom(parameters[0].ParameterType))
|
||||
{
|
||||
match = constructor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
return dynamicMethod;
|
||||
}
|
||||
|
||||
public override ObjectConstructor<object> CreateParametrizedConstructor(MethodBase method)
|
||||
public override ObjectConstructor<object> CreateParameterizedConstructor(MethodBase method)
|
||||
{
|
||||
DynamicMethod dynamicMethod = CreateDynamicMethod(method.ToString(), typeof(object), new[] { typeof(object[]) }, method.DeclaringType);
|
||||
ILGenerator generator = dynamicMethod.GetILGenerator();
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
get { return _instance; }
|
||||
}
|
||||
|
||||
public override ObjectConstructor<object> CreateParametrizedConstructor(MethodBase method)
|
||||
public override ObjectConstructor<object> CreateParameterizedConstructor(MethodBase method)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(method, "method");
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
MethodInfo seqType = _ofSeq.MakeGenericMethod(t);
|
||||
|
||||
return JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(seqType);
|
||||
return JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(seqType);
|
||||
}
|
||||
|
||||
public static ObjectConstructor<object> CreateMap(Type keyType, Type valueType)
|
||||
@@ -160,7 +160,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
Type genericMapType = _mapType.MakeGenericType(typeof(TKey), typeof(TValue));
|
||||
ConstructorInfo ctor = genericMapType.GetConstructor(new[] { typeof(IEnumerable<Tuple<TKey, TValue>>) });
|
||||
ObjectConstructor<object> ctorDelegate = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(ctor);
|
||||
ObjectConstructor<object> ctorDelegate = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(ctor);
|
||||
|
||||
ObjectConstructor<object> creator = args =>
|
||||
{
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
createdType = createdTypeDefinition.MakeGenericType(collectionItemType);
|
||||
MethodInfo method = mb.MakeGenericMethod(collectionItemType);
|
||||
parameterizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(method);
|
||||
parameterizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(method);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
createdType = createdTypeDefinition.MakeGenericType(keyItemType, valueItemType);
|
||||
MethodInfo method = mb.MakeGenericMethod(keyItemType, valueItemType);
|
||||
parameterizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(method);
|
||||
parameterizedCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParameterizedConstructor(method);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
get { return _instance; }
|
||||
}
|
||||
|
||||
public override ObjectConstructor<object> CreateParametrizedConstructor(MethodBase method)
|
||||
public override ObjectConstructor<object> CreateParameterizedConstructor(MethodBase method)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(method, "method");
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
}
|
||||
|
||||
public abstract MethodCall<T, object> CreateMethodCall<T>(MethodBase method);
|
||||
public abstract ObjectConstructor<object> CreateParametrizedConstructor(MethodBase method);
|
||||
public abstract ObjectConstructor<object> CreateParameterizedConstructor(MethodBase method);
|
||||
public abstract Func<T> CreateDefaultConstructor<T>(Type type);
|
||||
public abstract Func<T, object> CreateGet<T>(PropertyInfo propertyInfo);
|
||||
public abstract Func<T, object> CreateGet<T>(FieldInfo fieldInfo);
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
if (creator != null)
|
||||
{
|
||||
d.Creator = delegateFactory.CreateParametrizedConstructor(creator);
|
||||
d.Creator = delegateFactory.CreateParameterizedConstructor(creator);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user