From 723704464f0e4ea1ed31bd5489c62df2fcca1674 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 12 Oct 2015 21:40:00 +1300 Subject: [PATCH] -ShouldDeserialize PR cleanup --- .../Serialization/ShouldSerializeTests.cs | 81 +++++++++++++++++++ .../Serialization/JsonProperty.cs | 7 +- .../JsonSerializerInternalReader.cs | 17 ++-- 3 files changed, 95 insertions(+), 10 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Serialization/ShouldSerializeTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/ShouldSerializeTests.cs index b24475bb..bb23115c 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/ShouldSerializeTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/ShouldSerializeTests.cs @@ -27,7 +27,14 @@ using System; using System.Collections.Generic; using System.Globalization; using System.IO; +#if NET20 +using Newtonsoft.Json.Utilities.LinqBridge; +#else +using System.Linq; +#endif +using System.Reflection; using System.Text; +using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; #if NETFX_CORE using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; @@ -386,6 +393,45 @@ namespace Newtonsoft.Json.Tests.Serialization }", json); } + [Test] + public void ShouldDeserialize_True() + { + string json = @"{'HasName':true,'Name':'Name!'}"; + + MemoryTraceWriter traceWriter = new MemoryTraceWriter(); + ShouldDeserializeTestClass c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + ContractResolver = ShouldDeserializeContractResolver.Instance, + TraceWriter = traceWriter + }); + + Assert.AreEqual(null, c.ExtensionData); + Assert.AreEqual(true, c.HasName); + Assert.AreEqual("Name!", c.Name); + + Assert.IsTrue(traceWriter.GetTraceMessages().Any(m => m.EndsWith("Verbose ShouldDeserialize result for property 'Name' on Newtonsoft.Json.Tests.Serialization.ShouldDeserializeTestClass: True. Path 'Name'."))); + } + + [Test] + public void ShouldDeserialize_False() + { + string json = @"{'HasName':false,'Name':'Name!'}"; + + MemoryTraceWriter traceWriter = new MemoryTraceWriter(); + ShouldDeserializeTestClass c = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + ContractResolver = ShouldDeserializeContractResolver.Instance, + TraceWriter = traceWriter + }); + + Assert.AreEqual(1, c.ExtensionData.Count); + Assert.AreEqual("Name!", (string)c.ExtensionData["Name"]); + Assert.AreEqual(false, c.HasName); + Assert.AreEqual(null, c.Name); + + Assert.IsTrue(traceWriter.GetTraceMessages().Any(m => m.EndsWith("Verbose ShouldDeserialize result for property 'Name' on Newtonsoft.Json.Tests.Serialization.ShouldDeserializeTestClass: False. Path 'Name'."))); + } + public class Employee { public string Name { get; set; } @@ -588,4 +634,39 @@ namespace Newtonsoft.Json.Tests.Serialization return (name != null); } } + + public class ShouldDeserializeContractResolver : DefaultContractResolver + { + public static new readonly ShouldDeserializeContractResolver Instance = new ShouldDeserializeContractResolver(); + + protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) + { + JsonProperty property = base.CreateProperty(member, memberSerialization); + + MethodInfo shouldDeserializeMethodInfo = member.DeclaringType.GetMethod("ShouldDeserialize" + member.Name); + + if (shouldDeserializeMethodInfo != null) + { + property.ShouldDeserialize = o => + { + return (bool)shouldDeserializeMethodInfo.Invoke(o, null); + }; + } + + return property; + } + } + + public class ShouldDeserializeTestClass + { + [JsonExtensionData] + public IDictionary ExtensionData { get; set; } + public bool HasName { get; set; } + public string Name { get; set; } + + public bool ShouldDeserializeName() + { + return HasName; + } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs index daec3e00..3b7bbe68 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonProperty.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonProperty.cs @@ -235,11 +235,12 @@ namespace Newtonsoft.Json.Serialization /// /// A predicate used to determine whether the property should be serialize. public Predicate ShouldSerialize { get; set; } + /// - /// Gets or sets a predicate used to determine whether the property should be de-serialized. + /// Gets or sets a predicate used to determine whether the property should be deserialized. /// - /// A predicate used to determine whether the property should be de-serialized. - public Predicate ShouldDeSerialize { get; set; } + /// A predicate used to determine whether the property should be deserialized. + public Predicate ShouldDeserialize { get; set; } /// /// Gets or sets a predicate used to determine whether the property should be serialized. diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index 0b6198fe..9859c9bc 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -2051,7 +2051,7 @@ namespace Newtonsoft.Json.Serialization continue; } - if (!ShouldDeSerialize(reader, property, newObject)) + if (!ShouldDeserialize(reader, property, newObject)) { if (!reader.Read()) break; @@ -2105,19 +2105,22 @@ namespace Newtonsoft.Json.Serialization OnDeserialized(reader, contract, newObject); return newObject; } - //reader, contract, member, id - private bool ShouldDeSerialize(JsonReader reader, JsonProperty property, object target) + + private bool ShouldDeserialize(JsonReader reader, JsonProperty property, object target) { - if (property.ShouldDeSerialize == null) + if (property.ShouldDeserialize == null) return true; - bool shouldDeSerialize = property.ShouldDeSerialize(target); + bool shouldDeserialize = property.ShouldDeserialize(target); if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, reader.Path, "ShouldDeSerialize result for property '{0}' on {1}: {2}".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType, shouldDeSerialize)), null); + { + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, reader.Path, "ShouldDeserialize result for property '{0}' on {1}: {2}".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType, shouldDeserialize)), null); + } - return shouldDeSerialize; + return shouldDeserialize; } + private bool CheckPropertyName(JsonReader reader, string memberName) { if (Serializer.MetadataPropertyHandling == MetadataPropertyHandling.ReadAhead)