From c72f785b9c20328af42aa58ac1e99f32c0c0de52 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 12 Mar 2018 15:43:28 +1300 Subject: [PATCH] -Changed DataContractAttribute on collections back to array serialization -Fixed JObject.GetPropertyOwner to return value -Fixed JPropertyDescriptor GetValue and SetValue to return null for null owner --- Src/Newtonsoft.Json.Tests/Issues/Issue1598.cs | 14 +++++------ .../JPropertyDescriptorTests.cs | 16 +++++++++++++ .../Linq/JObjectTests.cs | 23 +++++++++++++++++++ Src/Newtonsoft.Json/Linq/JObject.cs | 5 ++++ .../Linq/JPropertyDescriptor.cs | 11 +++++---- .../Serialization/DefaultContractResolver.cs | 9 -------- 6 files changed, 57 insertions(+), 21 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Issues/Issue1598.cs b/Src/Newtonsoft.Json.Tests/Issues/Issue1598.cs index 85fbac3d..0689c841 100644 --- a/Src/Newtonsoft.Json.Tests/Issues/Issue1598.cs +++ b/Src/Newtonsoft.Json.Tests/Issues/Issue1598.cs @@ -60,13 +60,13 @@ namespace Newtonsoft.Json.Tests.Issues }; string json = JsonConvert.SerializeObject(activities, Formatting.Indented); - StringAssert.AreEqual(@"{ - ""List"": [ - { - ""Name"": ""An activity"" - } - ] -}", json); + // note that this has been reverted back in 11.0.2 because it is causing compat issues + // https://github.com/JamesNK/Newtonsoft.Json/issues/1627 + StringAssert.AreEqual(@"[ + { + ""Name"": ""An activity"" + } +]", json); } [Test] diff --git a/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs b/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs index 65a1312e..bcbf661e 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/ComponentModel/JPropertyDescriptorTests.cs @@ -50,6 +50,14 @@ namespace Newtonsoft.Json.Tests.Linq.ComponentModel Assert.AreEqual(o["prop2"], prop2.GetValue(o)); } + [Test] + public void GetValue_NullOwner_ReturnsNull() + { + JPropertyDescriptor prop1 = new JPropertyDescriptor("prop1"); + + Assert.AreEqual(null, prop1.GetValue(null)); + } + [Test] public void SetValue() { @@ -62,6 +70,14 @@ namespace Newtonsoft.Json.Tests.Linq.ComponentModel Assert.AreEqual("54321!", (string)o["prop1"]); } + [Test] + public void SetValue_NullOwner_NoError() + { + JPropertyDescriptor prop1 = new JPropertyDescriptor("prop1"); + + prop1.SetValue(null, "value!"); + } + [Test] public void ResetValue() { diff --git a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs index 04a1de1d..cabc77f9 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs @@ -2040,5 +2040,28 @@ Parameter name: arrayIndex"); ExceptionAssert.Throws(() => JObject.Parse(json), "Additional text encountered after finished reading JSON content: [. Path '', line 3, position 0."); } + +#if !(PORTABLE || DNXCORE50 || PORTABLE40) || NETSTANDARD2_0 + [Test] + public void GetPropertyOwner_ReturnsJObject() + { + ICustomTypeDescriptor o = new JObject + { + ["prop1"] = 1 + }; + + PropertyDescriptorCollection properties = o.GetProperties(); + Assert.AreEqual(1, properties.Count); + + PropertyDescriptor pd = properties[0]; + Assert.AreEqual("prop1", pd.Name); + + object owner = o.GetPropertyOwner(pd); + Assert.AreEqual(o, owner); + + object value = pd.GetValue(owner); + Assert.AreEqual(1, (int)(JToken)value); + } +#endif } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Linq/JObject.cs b/Src/Newtonsoft.Json/Linq/JObject.cs index 45e34f7b..bd2ac371 100644 --- a/Src/Newtonsoft.Json/Linq/JObject.cs +++ b/Src/Newtonsoft.Json/Linq/JObject.cs @@ -780,6 +780,11 @@ namespace Newtonsoft.Json.Linq object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) { + if (pd is JPropertyDescriptor) + { + return this; + } + return null; } #endregion diff --git a/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs b/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs index 960b0725..08858c03 100644 --- a/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs +++ b/Src/Newtonsoft.Json/Linq/JPropertyDescriptor.cs @@ -69,9 +69,7 @@ namespace Newtonsoft.Json.Linq /// The component with the property for which to retrieve the value. public override object GetValue(object component) { - JToken token = CastInstance(component)[Name]; - - return token; + return (component as JObject)?[Name]; } /// @@ -89,9 +87,12 @@ namespace Newtonsoft.Json.Linq /// The new value. public override void SetValue(object component, object value) { - JToken token = value as JToken ?? new JValue(value); + if (component is JObject o) + { + JToken token = value as JToken ?? new JValue(value); - CastInstance(component)[Name] = token; + o[Name] = token; + } } /// diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index 0c1f16ea..5fe7e13b 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -1176,15 +1176,6 @@ namespace Newtonsoft.Json.Serialization return CreateDictionaryContract(objectType); } -#if HAVE_DATA_CONTRACTS - // don't use GetDataContractAttribute because it looks for the attribute on base classes - DataContractAttribute dataContractAttribute = JsonTypeReflector.GetCachedAttribute(objectType); - if (dataContractAttribute != null) - { - return CreateObjectContract(objectType); - } -#endif - if (t == typeof(JToken) || t.IsSubclassOf(typeof(JToken))) { return CreateLinqContract(objectType);