diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs index 29a97f3c..8c39c7b3 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs @@ -33,7 +33,7 @@ using System.Threading.Tasks; #endif namespace Newtonsoft.Json.Tests.Serialization -{ +{ public class Staff { public string Name { get; set; } @@ -41,9 +41,86 @@ namespace Newtonsoft.Json.Tests.Serialization public IList Roles { get; set; } } + public class RoleTrace + { + public string Name { get; set; } + } + [TestFixture] public class TraceWriterTests : TestFixtureBase { + [Test] + public void DeserializedJsonWithAlreadyReadReader() + { + string json = @"{ 'name': 'Admin' }{ 'name': 'Publisher' }"; + IList roles = new List(); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + reader.SupportMultipleContent = true; + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter(); + while (true) + { + if (!reader.Read()) + { + break; + } + JsonSerializer serializer = new JsonSerializer(); + //the next line raise an exception + serializer.TraceWriter = traceWriter; + RoleTrace role = serializer.Deserialize(reader); + roles.Add(role); + } + + Assert.AreEqual("Admin", roles[0].Name); + Assert.AreEqual("Publisher", roles[1].Name); + + StringAssert.AreEqual(@"Deserialized JSON: +{ + ""name"": ""Admin"" +}", traceWriter.TraceRecords[2].Message); + + StringAssert.AreEqual(@"Deserialized JSON: +{ + ""name"": ""Publisher"" +}", traceWriter.TraceRecords[5].Message); + } + +#if !(NET20 || NET35 || NET40 || PORTABLE40 || PORTABLE) || DNXCORE50 + [Test] + public async Task DeserializedJsonWithAlreadyReadReader_Async() + { + string json = @"{ 'name': 'Admin' }{ 'name': 'Publisher' }"; + IList roles = new List(); + JsonTextReader reader = new JsonTextReader(new StringReader(json)); + reader.SupportMultipleContent = true; + InMemoryTraceWriter traceWriter = new InMemoryTraceWriter(); + while (true) + { + if (!await reader.ReadAsync()) + { + break; + } + JsonSerializer serializer = new JsonSerializer(); + //the next line raise an exception + serializer.TraceWriter = traceWriter; + RoleTrace role = serializer.Deserialize(reader); + roles.Add(role); + } + + Assert.AreEqual("Admin", roles[0].Name); + Assert.AreEqual("Publisher", roles[1].Name); + + StringAssert.AreEqual(@"Deserialized JSON: +{ + ""name"": ""Admin"" +}", traceWriter.TraceRecords[2].Message); + + StringAssert.AreEqual(@"Deserialized JSON: +{ + ""name"": ""Publisher"" +}", traceWriter.TraceRecords[5].Message); + } +#endif + #if !(PORTABLE || DNXCORE50 || PORTABLE40) || NETSTANDARD2_0 [Test] public void DiagnosticsTraceWriterTest() diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs index caf171d0..d08fdd0c 100644 --- a/Src/Newtonsoft.Json/JsonSerializer.cs +++ b/Src/Newtonsoft.Json/JsonSerializer.cs @@ -798,7 +798,7 @@ namespace Newtonsoft.Json SetupReader(reader, out previousCulture, out previousDateTimeZoneHandling, out previousDateParseHandling, out previousFloatParseHandling, out previousMaxDepth, out previousDateFormatString); TraceJsonReader traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - ? new TraceJsonReader(reader) + ? CreateTraceJsonReader(reader) : null; JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this); @@ -872,7 +872,7 @@ namespace Newtonsoft.Json SetupReader(reader, out previousCulture, out previousDateTimeZoneHandling, out previousDateParseHandling, out previousFloatParseHandling, out previousMaxDepth, out previousDateFormatString); TraceJsonReader traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) - ? new TraceJsonReader(reader) + ? CreateTraceJsonReader(reader) : null; JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this); @@ -1050,6 +1050,17 @@ namespace Newtonsoft.Json SerializeInternal(jsonWriter, value, null); } + private TraceJsonReader CreateTraceJsonReader(JsonReader reader) + { + TraceJsonReader traceReader = new TraceJsonReader(reader); + if (reader.TokenType != JsonToken.None) + { + traceReader.WriteCurrentToken(); + } + + return traceReader; + } + internal virtual void SerializeInternal(JsonWriter jsonWriter, object value, Type objectType) { ValidationUtils.ArgumentNotNull(jsonWriter, nameof(jsonWriter)); diff --git a/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs b/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs index 3c4518ba..47d2a9b9 100644 --- a/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs +++ b/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs @@ -32,56 +32,56 @@ namespace Newtonsoft.Json.Serialization public override bool Read() { bool value = _innerReader.Read(); - _textWriter.WriteToken(_innerReader, false, false, true); + WriteCurrentToken(); return value; } public override int? ReadAsInt32() { int? value = _innerReader.ReadAsInt32(); - _textWriter.WriteToken(_innerReader, false, false, true); + WriteCurrentToken(); return value; } public override string ReadAsString() { string value = _innerReader.ReadAsString(); - _textWriter.WriteToken(_innerReader, false, false, true); + WriteCurrentToken(); return value; } public override byte[] ReadAsBytes() { byte[] value = _innerReader.ReadAsBytes(); - _textWriter.WriteToken(_innerReader, false, false, true); + WriteCurrentToken(); return value; } public override decimal? ReadAsDecimal() { decimal? value = _innerReader.ReadAsDecimal(); - _textWriter.WriteToken(_innerReader, false, false, true); + WriteCurrentToken(); return value; } public override double? ReadAsDouble() { double? value = _innerReader.ReadAsDouble(); - _textWriter.WriteToken(_innerReader, false, false, true); + WriteCurrentToken(); return value; } public override bool? ReadAsBoolean() { bool? value = _innerReader.ReadAsBoolean(); - _textWriter.WriteToken(_innerReader, false, false, true); + WriteCurrentToken(); return value; } public override DateTime? ReadAsDateTime() { DateTime? value = _innerReader.ReadAsDateTime(); - _textWriter.WriteToken(_innerReader, false, false, true); + WriteCurrentToken(); return value; } @@ -89,11 +89,16 @@ namespace Newtonsoft.Json.Serialization public override DateTimeOffset? ReadAsDateTimeOffset() { DateTimeOffset? value = _innerReader.ReadAsDateTimeOffset(); - _textWriter.WriteToken(_innerReader, false, false, true); + WriteCurrentToken(); return value; } #endif + public void WriteCurrentToken() + { + _textWriter.WriteToken(_innerReader, false, false, true); + } + public override int Depth { get { return _innerReader.Depth; }