From 64414169eb0a1d7a949495e52d1a5ee98077efe0 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sun, 5 Aug 2012 14:20:17 +1200 Subject: [PATCH] -Fixed error handling serializing invalid JSON in certain cases --- .../JsonTextWriterTest.cs | 14 +++++ .../Properties/AssemblyInfo.cs | 2 +- .../SerializationErrorHandlingTests.cs | 60 +++++++++++++++++++ Src/Newtonsoft.Json/JsonWriter.cs | 4 +- .../Properties/AssemblyInfo.cs | 2 +- .../JsonSerializerInternalWriter.cs | 3 + 6 files changed, 82 insertions(+), 3 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs index 274f52ea..da896424 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs @@ -838,5 +838,19 @@ _____'propertyName': NaN Assert.AreEqual(@"""2000-01-01T01:01:01Z""", sw.ToString()); } + + [Test] + public void WriteEndOnProperty() + { + StringWriter sw = new StringWriter(); + JsonTextWriter writer = new JsonTextWriter(sw); + writer.QuoteChar = '\''; + + writer.WriteStartObject(); + writer.WritePropertyName("Blah"); + writer.WriteEnd(); + + Assert.AreEqual("{'Blah':null}", sw.ToString()); + } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index 6aa07234..a43ab900 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -72,5 +72,5 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.5.8.15204")] +[assembly: AssemblyFileVersion("4.5.8.15205")] #endif diff --git a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs index 3e394b0f..36d1cd83 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs @@ -27,6 +27,11 @@ using System; using System.Collections.Generic; using Newtonsoft.Json.Converters; using Newtonsoft.Json.Tests.TestObjects; +#if NET20 +using Newtonsoft.Json.Utilities.LinqBridge; +#else +using System.Linq; +#endif #if !NETFX_CORE using NUnit.Framework; #else @@ -641,6 +646,61 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual(@"Unexpected end when deserializing object. Path 'ChildObject.Integer', line 6, position 19.", errors[1]); } #endif + + [Test] + public void WriteEndOnPropertyState() + { + JsonSerializerSettings settings = new JsonSerializerSettings(); + settings.Error += (obj, args) => + { + args.ErrorContext.Handled = true; + }; + + var data = new List() + { + new ErrorPerson2{FirstName = "Scott", LastName = "Hanselman"}, + new ErrorPerson2{FirstName = "Scott", LastName = "Hunter"}, + new ErrorPerson2{FirstName = "Scott", LastName = "Guthrie"}, + }; + + var dictionary = data.GroupBy(person => person.FirstName).ToDictionary(group => @group.Key, group => @group.Cast()); + var output = JsonConvert.SerializeObject(dictionary, Formatting.None, settings); + Assert.AreEqual(@"{""Scott"":null}", output); + } + + [Test] + public void WriteEndOnPropertyState2() + { + JsonSerializerSettings settings = new JsonSerializerSettings(); + settings.Error += (obj, args) => + { + args.ErrorContext.Handled = true; + }; + + var data = new List + { + new ErrorPerson2 {FirstName = "Scott", LastName = "Hanselman"}, + new ErrorPerson2 {FirstName = "Scott", LastName = "Hunter"}, + new ErrorPerson2 {FirstName = "Scott", LastName = "Guthrie"}, + new ErrorPerson2 {FirstName = "James", LastName = "Newton-King"}, + }; + + var dictionary = data.GroupBy(person => person.FirstName).ToDictionary(group => @group.Key, group => @group.Cast()); + var output = JsonConvert.SerializeObject(dictionary, Formatting.None, settings); + + Assert.AreEqual(@"{""Scott"":null,""James"":null}", output); + } + } + + interface IErrorPerson2 + { + + } + + class ErrorPerson2//:IPerson - oops! Forgot to implement the person interface + { + public string LastName { get; set; } + public string FirstName { get; set; } } public class ThrowingReader : TextReader diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs index a15c84d1..4367efb7 100644 --- a/Src/Newtonsoft.Json/JsonWriter.cs +++ b/Src/Newtonsoft.Json/JsonWriter.cs @@ -582,7 +582,6 @@ namespace Newtonsoft.Json private void AutoCompleteClose(JsonToken tokenBeingClosed) { // write closing symbol and calculate new state - int levelsToComplete = 0; JsonContainerType type = GetTypeForCloseToken(tokenBeingClosed); @@ -612,6 +611,9 @@ namespace Newtonsoft.Json { JsonToken token = GetCloseTokenForType(Pop()); + if (_currentState == State.Property) + WriteNull(); + if (_formatting == Formatting.Indented) { if (_currentState != State.ObjectStart && _currentState != State.ArrayStart) diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index 47251bca..bcfabf8c 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -91,7 +91,7 @@ using System.Security; // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] #if !PocketPC -[assembly: AssemblyFileVersion("4.5.8.15204")] +[assembly: AssemblyFileVersion("4.5.8.15205")] #endif [assembly: CLSCompliant(true)] diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs index 73d7a2f7..e502cb61 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs @@ -804,6 +804,9 @@ To fix this error either change the environment to be fully trusted, change the { ClearErrorContext(); + if (writer.WriteState == WriteState.Property) + writer.WriteNull(); + while (writer.Top > initialDepth) { writer.WriteEnd();