-Added support for deserializing to readonly collections and dictionaries on classes with non-default constructors
This commit is contained in:
@@ -4441,5 +4441,75 @@ keyword such as type of business.""
|
||||
""newMemberWithProperty"": null
|
||||
}", result);
|
||||
}
|
||||
|
||||
public class NonDefaultConstructorWithReadOnlyCollectionProperty
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public IList<string> Categories { get; private set; }
|
||||
|
||||
public NonDefaultConstructorWithReadOnlyCollectionProperty(string title)
|
||||
{
|
||||
Title = title;
|
||||
Categories = new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NonDefaultConstructorWithReadOnlyCollectionPropertyTest()
|
||||
{
|
||||
NonDefaultConstructorWithReadOnlyCollectionProperty c1 = new NonDefaultConstructorWithReadOnlyCollectionProperty("blah");
|
||||
c1.Categories.Add("one");
|
||||
c1.Categories.Add("two");
|
||||
|
||||
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
|
||||
Assert.AreEqual(@"{
|
||||
""Title"": ""blah"",
|
||||
""Categories"": [
|
||||
""one"",
|
||||
""two""
|
||||
]
|
||||
}", json);
|
||||
|
||||
NonDefaultConstructorWithReadOnlyCollectionProperty c2 = JsonConvert.DeserializeObject<NonDefaultConstructorWithReadOnlyCollectionProperty>(json);
|
||||
Assert.AreEqual(c1.Title, c2.Title);
|
||||
Assert.AreEqual(c1.Categories.Count, c2.Categories.Count);
|
||||
Assert.AreEqual("one", c2.Categories[0]);
|
||||
Assert.AreEqual("two", c2.Categories[1]);
|
||||
}
|
||||
|
||||
public class NonDefaultConstructorWithReadOnlyDictionaryProperty
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public IDictionary<string, int> Categories { get; private set; }
|
||||
|
||||
public NonDefaultConstructorWithReadOnlyDictionaryProperty(string title)
|
||||
{
|
||||
Title = title;
|
||||
Categories = new Dictionary<string, int>();
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NonDefaultConstructorWithReadOnlyDictionaryPropertyTest()
|
||||
{
|
||||
NonDefaultConstructorWithReadOnlyDictionaryProperty c1 = new NonDefaultConstructorWithReadOnlyDictionaryProperty("blah");
|
||||
c1.Categories.Add("one", 1);
|
||||
c1.Categories.Add("two", 2);
|
||||
|
||||
string json = JsonConvert.SerializeObject(c1, Formatting.Indented);
|
||||
Assert.AreEqual(@"{
|
||||
""Title"": ""blah"",
|
||||
""Categories"": {
|
||||
""one"": 1,
|
||||
""two"": 2
|
||||
}
|
||||
}", json);
|
||||
|
||||
NonDefaultConstructorWithReadOnlyDictionaryProperty c2 = JsonConvert.DeserializeObject<NonDefaultConstructorWithReadOnlyDictionaryProperty>(json);
|
||||
Assert.AreEqual(c1.Title, c2.Title);
|
||||
Assert.AreEqual(c1.Categories.Count, c2.Categories.Count);
|
||||
Assert.AreEqual(1, c2.Categories["one"]);
|
||||
Assert.AreEqual(2, c2.Categories["two"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -915,7 +915,47 @@ namespace Newtonsoft.Json.Serialization
|
||||
object value = remainingPropertyValue.Value;
|
||||
|
||||
if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
|
||||
{
|
||||
property.ValueProvider.SetValue(createdObject, value);
|
||||
}
|
||||
else if (!property.Writable && value != null)
|
||||
{
|
||||
// handle readonly collection/dictionary properties
|
||||
JsonContract propertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType);
|
||||
|
||||
if (propertyContract is JsonArrayContract)
|
||||
{
|
||||
JsonArrayContract propertyArrayContract = propertyContract as JsonArrayContract;
|
||||
|
||||
object createdObjectCollection = property.ValueProvider.GetValue(createdObject);
|
||||
if (createdObjectCollection != null)
|
||||
{
|
||||
IWrappedCollection createdObjectCollectionWrapper = propertyArrayContract.CreateWrapper(createdObjectCollection);
|
||||
IWrappedCollection newValues = propertyArrayContract.CreateWrapper(value);
|
||||
|
||||
foreach (object newValue in newValues)
|
||||
{
|
||||
createdObjectCollectionWrapper.Add(newValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (propertyContract is JsonDictionaryContract)
|
||||
{
|
||||
JsonDictionaryContract jsonDictionaryContract = propertyContract as JsonDictionaryContract;
|
||||
|
||||
object createdObjectDictionary = property.ValueProvider.GetValue(createdObject);
|
||||
if (createdObjectDictionary != null)
|
||||
{
|
||||
IWrappedDictionary createdObjectDictionaryWrapper = jsonDictionaryContract.CreateWrapper(createdObjectDictionary);
|
||||
IWrappedDictionary newValues = jsonDictionaryContract.CreateWrapper(value);
|
||||
|
||||
foreach (DictionaryEntry newValue in newValues)
|
||||
{
|
||||
createdObjectDictionaryWrapper.Add(newValue.Key, newValue.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contract.InvokeOnDeserialized(createdObject, Serializer.Context);
|
||||
|
||||
Reference in New Issue
Block a user