diff --git a/Doc/SerializationSettings.aml b/Doc/SerializationSettings.aml index b33edf31..c518de8e 100644 --- a/Doc/SerializationSettings.aml +++ b/Doc/SerializationSettings.aml @@ -338,6 +338,19 @@ or a property's object properties or collection items using +
+ TraceWriter + The Json.NET serializer supports logging using the T:Newtonsoft.Json.Serialization.ITraceWriter + interface. By assigning a trace writer you can debug what is happening inside the Json.NET serializer when + serializing and deserializing JSON. + Read more about TraceWriters here: +Debug with Serialization Tracing +SerializationTracing.htm +_self + + +
+
Error The E:Newtonsoft.Json.JsonSerializer.Error event can catch errors during serialization and either handle the event and continue with diff --git a/Doc/SerializationTracing.aml b/Doc/SerializationTracing.aml new file mode 100644 index 00000000..39c32a12 --- /dev/null +++ b/Doc/SerializationTracing.aml @@ -0,0 +1,38 @@ + + + + + The Json.NET serializer supports logging using the T:Newtonsoft.Json.Serialization.ITraceWriter + interface. By assigning a trace writer you can debug what is happening inside the Json.NET serializer when + serializing and deserializing JSON. + +
+ ITraceWriter + + A trace writer can be assigned using properties on JsonSerializerSettings or JsonSerializer. + + + + Json.NET has two implementations of ITraceWriter: P:Newtonsoft.Json.Serialization.MemoryTraceWriter + which keeps messages in memory for simple debugging like the example + above, and T:Newtonsoft.Json.Serialization.DiagnosticsTraceWriter which writes messages to any + System.Diagnostics.TraceListeners your application is using. + +
+
+ Custom ITraceWriter + + To write messages using your existing logging framework implement a custom version of ITraceWriter. + + + + +
+ + T:Newtonsoft.Json.JsonSerializer + T:Newtonsoft.Json.Serialization.ITraceWriter + T:Newtonsoft.Json.Serialization.MemoryTraceWriter + T:Newtonsoft.Json.Serialization.DiagnosticsTraceWriter + +
+
\ No newline at end of file diff --git a/Doc/doc.content b/Doc/doc.content index 51d02d79..18929205 100644 --- a/Doc/doc.content +++ b/Doc/doc.content @@ -13,8 +13,9 @@ - + + diff --git a/Doc/doc.shfbproj b/Doc/doc.shfbproj index ce7cf2bd..0bdcc7a0 100644 --- a/Doc/doc.shfbproj +++ b/Doc/doc.shfbproj @@ -137,6 +137,7 @@ + diff --git a/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs new file mode 100644 index 00000000..9c047486 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs @@ -0,0 +1,163 @@ +#region License +// Copyright (c) 2007 James Newton-King +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +#endregion + +#if !(NET35 || NET20 || PORTABLE) +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Dynamic; +using System.IO; +using System.Linq; +using System.Net; +using System.Reflection; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +#if !NETFX_CORE +using NUnit.Framework; +#else +using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; +using TestFixture = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute; +using Test = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute; +#endif +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Tests.Serialization; +using Newtonsoft.Json.Tests.TestObjects; +using Newtonsoft.Json.Utilities; +using System.Globalization; + +namespace Newtonsoft.Json.Tests.Documentation +{ + [TestFixture] + public class TraceWriterTests : TestFixtureBase + { + public class LogEventInfo + { + public LogLevel Level; + public string Message; + public Exception Exception; + } + + public class LogLevel + { + public static LogLevel Info; + public static LogLevel Trace; + public static LogLevel Error; + public static LogLevel Warn; + public static LogLevel Off; + } + + public class Logger + { + public void Log(LogEventInfo logEvent) + { + } + } + + public static class LogManager + { + public static Logger GetLogger(string className) + { + return new Logger(); + } + } + + #region CustomTraceWriterExample + public class NLogTraceWriter : ITraceWriter + { + private static readonly Logger Logger = LogManager.GetLogger("NLogTraceWriter"); + + public TraceLevel LevelFilter + { + // trace all messages. nlog can handle filtering + get { return TraceLevel.Verbose; } + } + + private LogLevel GetLogLevel(TraceLevel level) + { + switch (level) + { + case TraceLevel.Error: + return LogLevel.Error; + case TraceLevel.Warning: + return LogLevel.Warn; + case TraceLevel.Info: + return LogLevel.Info; + case TraceLevel.Off: + return LogLevel.Off; + default: + return LogLevel.Trace; + } + } + + public void Trace(TraceLevel level, string message, Exception ex) + { + LogEventInfo logEvent = new LogEventInfo + { + Message = message, + Level = GetLogLevel(level), + Exception = ex + }; + + Logger.Log(logEvent); + } + } + #endregion + + [Test] + public void MemoryTraceWriterTest() + { + #region MemoryTraceWriterExample + Staff staff = new Staff(); + staff.Name = "Arnie Admin"; + staff.Roles = new List { "Administrator" }; + staff.StartDate = DateTime.Now; + + ITraceWriter traceWriter = new MemoryTraceWriter(); + + JsonConvert.SerializeObject( + staff, + new JsonSerializerSettings { TraceWriter = traceWriter, Converters = { new JavaScriptDateTimeConverter() } }); + + Console.WriteLine(traceWriter); + // 2012-11-11T12:08:42.761 Info Started serializing Newtonsoft.Json.Tests.Serialization.Staff. Path ''. + // 2012-11-11T12:08:42.785 Info Started serializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path 'StartDate'. + // 2012-11-11T12:08:42.791 Info Finished serializing System.DateTime with converter Newtonsoft.Json.Converters.JavaScriptDateTimeConverter. Path 'StartDate'. + // 2012-11-11T12:08:42.797 Info Started serializing System.Collections.Generic.List`1[System.String]. Path 'Roles'. + // 2012-11-11T12:08:42.798 Info Finished serializing System.Collections.Generic.List`1[System.String]. Path 'Roles'. + // 2012-11-11T12:08:42.799 Info Finished serializing Newtonsoft.Json.Tests.Serialization.Staff. Path ''. + #endregion + + MemoryTraceWriter memoryTraceWriter = (MemoryTraceWriter)traceWriter; + + Assert.AreEqual(743, memoryTraceWriter.ToString().Length); + Assert.AreEqual(6, memoryTraceWriter.GetTraceMessages().Count()); + } + } +} +#endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj index f89253c0..8cf13318 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj @@ -118,6 +118,7 @@ + diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs index 74f0b891..39f0215d 100644 --- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs +++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs @@ -320,7 +320,6 @@ If attributes are not mentioned, default values are used in each case. TimeOperation(() => { - string json = null; for (int i = 0; i < interations; i++) { using (StringWriter w = StringUtils.CreateStringWriter(StringUtils.GetLength(text) ?? 16))