From 6173ca1574de47075630f0ce52314778ab60e5bb Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sun, 14 Jun 2015 15:55:24 +1200 Subject: [PATCH] -Fixed invalid Required.Always error with constructor property name casing -Fixed empty string coerce check with Required.Always and constructor --- .../Serialization/JsonSerializerTest.cs | 39 +++++++++++++++++++ .../JsonSerializerInternalReader.cs | 23 ++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index d89b7ace..b77d9f49 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -95,6 +95,36 @@ namespace Newtonsoft.Json.Tests.Serialization [TestFixture] public class JsonSerializerTest : TestFixtureBase { + [Test] + public void CaseInsensitiveRequiredPropertyConstructorCreation() + { + FooRequired foo1 = new FooRequired(new[] { "A", "B", "C" }); + string json = JsonConvert.SerializeObject(foo1); + + StringAssert.AreEqual(@"{""Bars"":[""A"",""B"",""C""]}", json); + + FooRequired foo2 = JsonConvert.DeserializeObject(json); + Assert.AreEqual(foo1.Bars.Count, foo2.Bars.Count); + Assert.AreEqual(foo1.Bars[0], foo2.Bars[0]); + Assert.AreEqual(foo1.Bars[1], foo2.Bars[1]); + Assert.AreEqual(foo1.Bars[2], foo2.Bars[2]); + } + + public class FooRequired + { + [JsonProperty(Required = Required.Always)] + public List Bars { get; private set; } + + public FooRequired(IEnumerable bars) + { + Bars = new List(); + if (bars != null) + { + Bars.AddRange(bars); + } + } + } + [Test] public void CoercedEmptyStringWithRequired() { @@ -104,6 +134,15 @@ namespace Newtonsoft.Json.Tests.Serialization }, "Required property 'RequiredProperty' expects a value but got null. Path '', line 1, position 21."); } + [Test] + public void CoercedEmptyStringWithRequiredConstructor() + { + ExceptionAssert.Throws(() => + { + JsonConvert.DeserializeObject("{Bars:''}"); + }, "Required property 'Bars' expects a value but got null. Path '', line 1, position 9."); + } + public class Binding { [JsonProperty(Required = Required.Always)] diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index f3ee071f..bf5c2426 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -1661,9 +1661,28 @@ namespace Newtonsoft.Json.Serialization if (propertiesPresence != null) { // map from creator property to normal property - JsonProperty presenceProperty = propertiesPresence.Keys.FirstOrDefault(p => p.PropertyName == property.PropertyName); + JsonProperty presenceProperty = propertiesPresence.Keys.ForgivingCaseSensitiveFind(p => p.PropertyName, property.PropertyName); if (presenceProperty != null) - propertiesPresence[presenceProperty] = (propertyValue.Value == null) ? PropertyPresence.Null : PropertyPresence.Value; + { + object v = propertyValue.Value; + PropertyPresence propertyPresence; + if (v == null) + { + propertyPresence = PropertyPresence.Null; + } + else if (v is string) + { + propertyPresence = CoerceEmptyStringToNull(property.PropertyType, property.PropertyContract, (string)v) + ? PropertyPresence.Null + : PropertyPresence.Value; + } + else + { + propertyPresence = PropertyPresence.Value; + } + + propertiesPresence[presenceProperty] = propertyPresence; + } } }