From 803403ae2190b6ffd863a0f2b02f0d17d3e2571e Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sat, 5 Nov 2016 23:21:34 +1300 Subject: [PATCH] -Fixed deserializing generic only IList types with a constructor override --- .../JsonSerializerCollectionsTests.cs | 106 ++++++++++++++++++ .../JsonSerializerInternalReader.cs | 9 +- 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs index bee814ff..90430dc4 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerCollectionsTests.cs @@ -1944,6 +1944,112 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual("replaced!", result.Person["groups"]); } #endif + + [Test] + public void GenericIListAndOverrideConstructor() + { + MyClass deserialized = JsonConvert.DeserializeObject(@"[""apple"", ""monkey"", ""goose""]"); + + Assert.AreEqual("apple", deserialized[0]); + Assert.AreEqual("monkey", deserialized[1]); + Assert.AreEqual("goose", deserialized[2]); + } + + public class MyClass : IList + { + private List _storage; + + [JsonConstructor] + private MyClass() + { + _storage = new List(); + } + + public MyClass(IEnumerable source) + { + _storage = new List(source); + } + + //Below is generated by VS to implement IList + public string this[int index] + { + get + { + return ((IList)_storage)[index]; + } + + set + { + ((IList)_storage)[index] = value; + } + } + + public int Count + { + get + { + return ((IList)_storage).Count; + } + } + + public bool IsReadOnly + { + get + { + return ((IList)_storage).IsReadOnly; + } + } + + public void Add(string item) + { + ((IList)_storage).Add(item); + } + + public void Clear() + { + ((IList)_storage).Clear(); + } + + public bool Contains(string item) + { + return ((IList)_storage).Contains(item); + } + + public void CopyTo(string[] array, int arrayIndex) + { + ((IList)_storage).CopyTo(array, arrayIndex); + } + + public IEnumerator GetEnumerator() + { + return ((IList)_storage).GetEnumerator(); + } + + public int IndexOf(string item) + { + return ((IList)_storage).IndexOf(item); + } + + public void Insert(int index, string item) + { + ((IList)_storage).Insert(index, item); + } + + public bool Remove(string item) + { + return ((IList)_storage).Remove(item); + } + + public void RemoveAt(int index) + { + ((IList)_storage).RemoveAt(index); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return ((IList)_storage).GetEnumerator(); + } + } } #if !NET20 && !PORTABLE40 diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index 0cd31eb1..44507b2a 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -1176,8 +1176,15 @@ namespace Newtonsoft.Json.Serialization } else { + object list = contract.OverrideCreator(); + + if (contract.ShouldCreateWrapper) + { + list = contract.CreateWrapper(list); + } + createdFromNonDefaultCreator = false; - return (IList)contract.OverrideCreator(); + return (IList)list; } } else if (contract.IsReadOnlyOrFixedSize)