From f7018719d4d0f4cebbd42963115e8ad6d36b6ccf Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Mon, 12 Nov 2012 22:24:26 +1300 Subject: [PATCH] -Trace ShouldSerialize and IsSpecified --- .../Properties/AssemblyInfo.cs | 2 +- .../Serialization/JsonSerializerTest.cs | 109 +++++++++-------- .../Serialization/TraceWriterTests.cs | 110 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 2 +- .../JsonSerializerInternalReader.cs | 5 + .../JsonSerializerInternalWriter.cs | 20 +++- 6 files changed, 186 insertions(+), 62 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index aeb236f9..de5e070e 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -76,5 +76,5 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.5.10.15511")] +[assembly: AssemblyFileVersion("4.5.10.15512")] #endif diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index 811d90da..8c9fab92 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -3847,24 +3847,6 @@ To fix this error either change the environment to be fully trusted, change the Assert.AreEqual(null, cc.Ignored); } - public class ShouldSerializeTestClass - { - internal bool _shouldSerializeName; - - public string Name { get; set; } - public int Age { get; set; } - - public void ShouldSerializeAge() - { - // dummy. should never be used because it doesn't return bool - } - - public bool ShouldSerializeName() - { - return _shouldSerializeName; - } - } - [Test] public void ShouldSerializeTest() { @@ -3929,43 +3911,6 @@ To fix this error either change the environment to be fully trusted, change the Console.WriteLine(json); } - public class SpecifiedTestClass - { - private bool _nameSpecified; - - public string Name { get; set; } - public int Age { get; set; } - public int Weight { get; set; } - public int Height { get; set; } - public int FavoriteNumber { get; set; } - - // dummy. should never be used because it isn't of type bool - [JsonIgnore] - public long AgeSpecified { get; set; } - - [JsonIgnore] - public bool NameSpecified - { - get { return _nameSpecified; } - set { _nameSpecified = value; } - } - - [JsonIgnore] - public bool WeightSpecified; - - [JsonIgnore] - [System.Xml.Serialization.XmlIgnoreAttribute] - public bool HeightSpecified; - - [JsonIgnore] - - public bool FavoriteNumberSpecified - { - // get only example - get { return FavoriteNumber != 0; } - } - } - [Test] public void SpecifiedTest() { @@ -7559,4 +7504,58 @@ Parameter name: value", return objectType == typeof (int); } } + + public class ShouldSerializeTestClass + { + internal bool _shouldSerializeName; + + public string Name { get; set; } + public int Age { get; set; } + + public void ShouldSerializeAge() + { + // dummy. should never be used because it doesn't return bool + } + + public bool ShouldSerializeName() + { + return _shouldSerializeName; + } + } + + public class SpecifiedTestClass + { + private bool _nameSpecified; + + public string Name { get; set; } + public int Age { get; set; } + public int Weight { get; set; } + public int Height { get; set; } + public int FavoriteNumber { get; set; } + + // dummy. should never be used because it isn't of type bool + [JsonIgnore] + public long AgeSpecified { get; set; } + + [JsonIgnore] + public bool NameSpecified + { + get { return _nameSpecified; } + set { _nameSpecified = value; } + } + + [JsonIgnore] + public bool WeightSpecified; + + [JsonIgnore] + [System.Xml.Serialization.XmlIgnoreAttribute] + public bool HeightSpecified; + + [JsonIgnore] + public bool FavoriteNumberSpecified + { + // get only example + get { return FavoriteNumber != 0; } + } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs index 50e420cb..5523938a 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs @@ -534,6 +534,116 @@ Newtonsoft.Json Error: 0 : Error! Assert.AreEqual("Started deserializing System.Version. Path '', line 9, position 2.", traceWriter.TraceRecords[2].Message); Assert.AreEqual("Finished deserializing System.Version. Path '', line 9, position 2.", traceWriter.TraceRecords[3].Message); } + + [Test] + public void ShouldSerializeTestClass() + { + ShouldSerializeTestClass c = new ShouldSerializeTestClass(); + c.Age = 29; + c.Name = "Jim"; + c._shouldSerializeName = true; + + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; + + JsonConvert.SerializeObject(c, new JsonSerializerSettings {TraceWriter = traceWriter}); + + Assert.AreEqual("ShouldSerialize result for property 'Name' on Newtonsoft.Json.Tests.Serialization.ShouldSerializeTestClass: True. Path ''.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual(TraceLevel.Verbose, traceWriter.TraceRecords[1].Level); + + traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; + + c._shouldSerializeName = false; + + JsonConvert.SerializeObject(c, new JsonSerializerSettings { TraceWriter = traceWriter }); + + Assert.AreEqual("ShouldSerialize result for property 'Name' on Newtonsoft.Json.Tests.Serialization.ShouldSerializeTestClass: False. Path ''.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual(TraceLevel.Verbose, traceWriter.TraceRecords[1].Level); + } + + [Test] + public void SpecifiedTest() + { + SpecifiedTestClass c = new SpecifiedTestClass(); + c.Name = "James"; + c.Age = 27; + c.NameSpecified = false; + + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; + + string json = JsonConvert.SerializeObject(c, Formatting.Indented, new JsonSerializerSettings { TraceWriter = traceWriter }); + + Assert.AreEqual("Started serializing Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass. Path ''.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("IsSpecified result for property 'Name' on Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass: False. Path ''.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual("IsSpecified result for property 'Weight' on Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass: False. Path 'Age'.", traceWriter.TraceRecords[2].Message); + Assert.AreEqual("IsSpecified result for property 'Height' on Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass: False. Path 'Age'.", traceWriter.TraceRecords[3].Message); + Assert.AreEqual("IsSpecified result for property 'FavoriteNumber' on Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass: False. Path 'Age'.", traceWriter.TraceRecords[4].Message); + Assert.AreEqual("Finished serializing Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass. Path ''.", traceWriter.TraceRecords[5].Message); + + Assert.AreEqual(@"{ + ""Age"": 27 +}", json); + + traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; + + SpecifiedTestClass deserialized = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { TraceWriter = traceWriter }); + + Assert.AreEqual("Started deserializing Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass. Path 'Age', line 2, position 9.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("Finished deserializing Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass. Path '', line 3, position 2.", traceWriter.TraceRecords[1].Message); + + Assert.IsNull(deserialized.Name); + Assert.IsFalse(deserialized.NameSpecified); + Assert.IsFalse(deserialized.WeightSpecified); + Assert.IsFalse(deserialized.HeightSpecified); + Assert.IsFalse(deserialized.FavoriteNumberSpecified); + Assert.AreEqual(27, deserialized.Age); + + c.NameSpecified = true; + c.WeightSpecified = true; + c.HeightSpecified = true; + c.FavoriteNumber = 23; + json = JsonConvert.SerializeObject(c, Formatting.Indented); + + Assert.AreEqual(@"{ + ""Name"": ""James"", + ""Age"": 27, + ""Weight"": 0, + ""Height"": 0, + ""FavoriteNumber"": 23 +}", json); + + traceWriter = new InMemoryTraceWriter + { + LevelFilter = TraceLevel.Verbose + }; + + deserialized = JsonConvert.DeserializeObject(json, new JsonSerializerSettings { TraceWriter = traceWriter }); + + Assert.AreEqual("Started deserializing Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass. Path 'Name', line 2, position 10.", traceWriter.TraceRecords[0].Message); + Assert.AreEqual("IsSpecified for property 'Name' on Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass set to true. Path 'Name', line 2, position 18.", traceWriter.TraceRecords[1].Message); + Assert.AreEqual("IsSpecified for property 'Weight' on Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass set to true. Path 'Weight', line 4, position 14.", traceWriter.TraceRecords[2].Message); + Assert.AreEqual("IsSpecified for property 'Height' on Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass set to true. Path 'Height', line 5, position 14.", traceWriter.TraceRecords[3].Message); + Assert.AreEqual("Finished deserializing Newtonsoft.Json.Tests.Serialization.SpecifiedTestClass. Path '', line 7, position 2.", traceWriter.TraceRecords[4].Message); + + Assert.AreEqual("James", deserialized.Name); + Assert.IsTrue(deserialized.NameSpecified); + Assert.IsTrue(deserialized.WeightSpecified); + Assert.IsTrue(deserialized.HeightSpecified); + Assert.IsTrue(deserialized.FavoriteNumberSpecified); + Assert.AreEqual(27, deserialized.Age); + Assert.AreEqual(23, deserialized.FavoriteNumber); + } } public class TraceRecord diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index b8960ba4..837296a6 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -90,7 +90,7 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.5.10.15511")] +[assembly: AssemblyFileVersion("4.5.10.15512")] #endif [assembly: CLSCompliant(true)] diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index 7e662115..90b12b57 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -701,7 +701,12 @@ To fix this error either change the JSON to a {1} or change the deserialized typ property.ValueProvider.SetValue(target, value); if (property.SetIsSpecified != null) + { + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "IsSpecified for property '{0}' on {1} set to true.".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType)), null); + property.SetIsSpecified(target, true); + } } } diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs index c07f52c9..f51d5bf0 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs @@ -393,7 +393,7 @@ namespace Newtonsoft.Json.Serialization private bool CalculatePropertyValues(JsonWriter writer, object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, out JsonContract memberContract, out object memberValue) { - if (!property.Ignored && property.Readable && ShouldSerialize(property, value) && IsSpecified(property, value)) + if (!property.Ignored && property.Readable && ShouldSerialize(writer, property, value) && IsSpecified(writer, property, value)) { if (property.PropertyContract == null) property.PropertyContract = Serializer.ContractResolver.ResolveContract(property.PropertyType); @@ -873,20 +873,30 @@ To fix this error either change the environment to be fully trusted, change the } } - private bool ShouldSerialize(JsonProperty property, object target) + private bool ShouldSerialize(JsonWriter writer, JsonProperty property, object target) { if (property.ShouldSerialize == null) return true; - return property.ShouldSerialize(target); + bool shouldSerialize = property.ShouldSerialize(target); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "ShouldSerialize result for property '{0}' on {1}: {2}".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType, shouldSerialize)), null); + + return shouldSerialize; } - private bool IsSpecified(JsonProperty property, object target) + private bool IsSpecified(JsonWriter writer, JsonProperty property, object target) { if (property.GetIsSpecified == null) return true; - return property.GetIsSpecified(target); + bool isSpecified = property.GetIsSpecified(target); + + if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + TraceWriter.Trace(TraceLevel.Verbose, JsonPosition.FormatMessage(null, writer.Path, "IsSpecified result for property '{0}' on {1}: {2}".FormatWith(CultureInfo.InvariantCulture, property.PropertyName, property.DeclaringType, isSpecified)), null); + + return isSpecified; } } } \ No newline at end of file