Fix deserialize via ctor with some existing collection types (#2151)

This commit is contained in:
James Newton-King
2019-09-08 20:46:20 +12:00
committed by GitHub
parent c5f2103470
commit a213bac448
2 changed files with 34 additions and 4 deletions
@@ -62,6 +62,29 @@ namespace Newtonsoft.Json.Tests.Serialization
public class JsonSerializerCollectionsTests : TestFixtureBase
{
#if !(NET35 || NET20 || PORTABLE || PORTABLE40) || NETSTANDARD2_0
[Test]
public void DeserializeNonGenericListTypeAndReadOnlyListViaConstructor()
{
ConstructorCollectionContainer a = JsonConvert.DeserializeObject<ConstructorCollectionContainer>("{'a':1,'b':['aaa'],'c':['aaa']}");
Assert.AreEqual(1, a.A);
Assert.AreEqual(1, a.B.Count());
Assert.AreEqual("aaa", a.B.ElementAt(0));
Assert.AreEqual(0, a.C.Count());
}
public class ConstructorCollectionContainer
{
public int A { get; }
public IEnumerable<string> B { get; } = new SortedSet<string>();
public IEnumerable<string> C { get; } = new List<string>().AsReadOnly();
public ConstructorCollectionContainer(int a)
{
this.A = a;
}
}
[Test]
public void DeserializeConcurrentDictionaryWithNullValue()
{
@@ -2079,12 +2079,19 @@ namespace Newtonsoft.Json.Serialization
object? createdObjectCollection = property.ValueProvider!.GetValue(createdObject);
if (createdObjectCollection != null)
{
IList createdObjectCollectionWrapper = (propertyArrayContract.ShouldCreateWrapper) ? propertyArrayContract.CreateWrapper(createdObjectCollection) : (IList)createdObjectCollection;
IList newValues = (propertyArrayContract.ShouldCreateWrapper) ? propertyArrayContract.CreateWrapper(value) : (IList)value;
propertyArrayContract = (JsonArrayContract)GetContract(createdObjectCollection.GetType());
foreach (object newValue in newValues)
IList createdObjectCollectionWrapper = (propertyArrayContract.ShouldCreateWrapper) ? propertyArrayContract.CreateWrapper(createdObjectCollection) : (IList)createdObjectCollection;
// Don't attempt to populate array/read-only list
if (!createdObjectCollectionWrapper.IsFixedSize)
{
createdObjectCollectionWrapper.Add(newValue);
IList newValues = (propertyArrayContract.ShouldCreateWrapper) ? propertyArrayContract.CreateWrapper(value) : (IList)value;
foreach (object newValue in newValues)
{
createdObjectCollectionWrapper.Add(newValue);
}
}
}
}