From f68794d2063b4a2d74f2e875bc971e69afd53976 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sun, 19 May 2013 22:34:21 +1200 Subject: [PATCH] -Added serialized/deserialized JSON when verbose tracing -Fixed not using default serializer settings with primitive values and JToken.ToObject -Fixed error writing BigIntegers with JsonWriter.WriteToken --- .../Documentation/TraceWriterTests.cs | 16 +- Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs | 25 ++ .../Newtonsoft.Json.Tests.Net35.csproj | 4 +- .../Properties/AssemblyInfo.cs | 2 +- .../DefaultValueHandlingTests.cs | 25 ++ .../Serialization/TraceWriterTests.cs | 313 +++++++++++++++- Src/Newtonsoft.Json/JsonSerializer.cs | 19 +- Src/Newtonsoft.Json/JsonWriter.cs | 24 +- Src/Newtonsoft.Json/Linq/JToken.cs | 161 ++++---- .../Newtonsoft.Json.Net20.csproj | 2 + .../Newtonsoft.Json.Net35.csproj | 2 + .../Newtonsoft.Json.Net40.csproj | 2 + .../Newtonsoft.Json.Portable.csproj | 2 + .../Newtonsoft.Json.Portable40.csproj | 2 + Src/Newtonsoft.Json/Newtonsoft.Json.csproj | 2 + .../Properties/AssemblyInfo.cs | 2 +- .../JsonSerializerInternalReader.cs | 2 +- .../Serialization/TraceJsonReader.cs | 140 +++++++ .../Serialization/TraceJsonWriter.cs | 348 ++++++++++++++++++ 19 files changed, 996 insertions(+), 97 deletions(-) create mode 100644 Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs create mode 100644 Src/Newtonsoft.Json/Serialization/TraceJsonWriter.cs diff --git a/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs b/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs index 7060640e..d12570ad 100644 --- a/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Documentation/TraceWriterTests.cs @@ -137,7 +137,7 @@ namespace Newtonsoft.Json.Tests.Documentation Staff staff = new Staff(); staff.Name = "Arnie Admin"; staff.Roles = new List { "Administrator" }; - staff.StartDate = DateTime.Now; + staff.StartDate = new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc); ITraceWriter traceWriter = new MemoryTraceWriter(); @@ -152,12 +152,22 @@ namespace Newtonsoft.Json.Tests.Documentation // 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 ''. + // 2013-05-18T21:38:11.255 Verbose Serialized JSON: + // { + // "Name": "Arnie Admin", + // "StartDate": new Date( + // 976623132000 + // ), + // "Roles": [ + // "Administrator" + // ] + // } #endregion MemoryTraceWriter memoryTraceWriter = (MemoryTraceWriter)traceWriter; - Assert.AreEqual(743, memoryTraceWriter.ToString().Length); - Assert.AreEqual(6, memoryTraceWriter.GetTraceMessages().Count()); + Assert.AreEqual(916, memoryTraceWriter.ToString().Length); + Assert.AreEqual(7, memoryTraceWriter.GetTraceMessages().Count()); } } } diff --git a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs index 96c0ae9b..8e8beb81 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs @@ -44,6 +44,7 @@ using Newtonsoft.Json.Utilities.LinqBridge; #else using System.Linq; #endif +using Newtonsoft.Json.Tests.Serialization; namespace Newtonsoft.Json.Tests.Linq { @@ -63,6 +64,30 @@ namespace Newtonsoft.Json.Tests.Linq Assert.AreEqual(typeof(decimal), v.Value.GetType()); } + [Test] + public void ToObjectWithDefaultSettings() + { + try + { + JsonConvert.DefaultSettings = () => + { + return new JsonSerializerSettings + { + Converters = { new MetroStringConverter() } + }; + }; + + JValue v = new JValue(":::STRING:::"); + string s = v.ToObject(); + + Assert.AreEqual("string", s); + } + finally + { + JsonConvert.DefaultSettings = null; + } + } + [Test] public void ChangeValue() { diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj index 5d191e59..fc27673e 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net35.csproj @@ -150,7 +150,9 @@ - + + Component + diff --git a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs index 872f9349..5f1f8699 100644 --- a/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json.Tests/Properties/AssemblyInfo.cs @@ -75,4 +75,4 @@ using System.Security; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] -[assembly: AssemblyFileVersion("5.0.4.16105")] +[assembly: AssemblyFileVersion("5.0.5.16119")] diff --git a/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs index 1a3c23d1..0c9dc869 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/DefaultValueHandlingTests.cs @@ -313,8 +313,33 @@ namespace Newtonsoft.Json.Tests.Serialization Assert.AreEqual(0, o.IntValue2); Assert.AreEqual(null, o.ClassValue); } + +#if !NET20 + [Test] + public void EmitDefaultValueIgnoreAndPopulate() + { + string str = "{}"; + TestClass obj = JsonConvert.DeserializeObject(str, new JsonSerializerSettings + { + DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate + }); + + Assert.AreEqual("fff", obj.Field1); + } +#endif } +#if !NET20 + [DataContract] + public class TestClass + { + [JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)] + [DataMember(EmitDefaultValue = false)] + [DefaultValue("fff")] + public string Field1 { set; get; } + } +#endif + public class DefaultValueHandlingDeserialize { public string Derp { get; set; } diff --git a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs index 93a33dd9..a07327e0 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/TraceWriterTests.cs @@ -3,6 +3,9 @@ using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) +using System.Numerics; +#endif using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters; using System.Text; @@ -68,12 +71,12 @@ Newtonsoft.Json Error: 0 : Error! #endif [Test] - public void MemoryTraceWriterTest() + public void MemoryTraceWriterSerializeTest() { Staff staff = new Staff(); staff.Name = "Arnie Admin"; staff.Roles = new List {"Administrator"}; - staff.StartDate = DateTime.Now; + staff.StartDate = new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc); ITraceWriter traceWriter = new MemoryTraceWriter(); @@ -90,9 +93,74 @@ Newtonsoft.Json Error: 0 : Error! // 2012-11-11T12:08:42.799 Info Finished serializing Newtonsoft.Json.Tests.Serialization.Staff. Path ''. MemoryTraceWriter memoryTraceWriter = (MemoryTraceWriter)traceWriter; + string output = memoryTraceWriter.ToString(); - Assert.AreEqual(743, memoryTraceWriter.ToString().Length); - Assert.AreEqual(6, memoryTraceWriter.GetTraceMessages().Count()); + Assert.AreEqual(916, output.Length); + Assert.AreEqual(7, memoryTraceWriter.GetTraceMessages().Count()); + + string json = @"Serialized JSON: +{ + ""Name"": ""Arnie Admin"", + ""StartDate"": new Date( + 976623132000 + ), + ""Roles"": [ + ""Administrator"" + ] +}"; + + Assert.IsTrue(output.Contains(json)); + } + + [Test] + public void MemoryTraceWriterDeserializeTest() + { + string json = @"{ + ""Name"": ""Arnie Admin"", + ""StartDate"": new Date( + 976623132000 + ), + ""Roles"": [ + ""Administrator"" + ] +}"; + + Staff staff = new Staff(); + staff.Name = "Arnie Admin"; + staff.Roles = new List { "Administrator" }; + staff.StartDate = new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc); + + ITraceWriter traceWriter = new MemoryTraceWriter(); + + JsonConvert.DeserializeObject( + json, + 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 ''. + // 2013-05-19T00:07:24.360 Verbose Deserialized JSON: + // { + // "Name": "Arnie Admin", + // "StartDate": new Date( + // 976623132000 + // ), + // "Roles": [ + // "Administrator" + // ] + // } + + MemoryTraceWriter memoryTraceWriter = (MemoryTraceWriter)traceWriter; + string output = memoryTraceWriter.ToString(); + + Assert.AreEqual(1059, output.Length); + Assert.AreEqual(7, memoryTraceWriter.GetTraceMessages().Count()); + + Assert.IsTrue(output.Contains(json)); } [Test] @@ -152,6 +220,8 @@ Newtonsoft.Json Error: 0 : Error! Assert.AreEqual("Started serializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path 'StringDictionary'.", traceWriter.TraceRecords[7].Message); Assert.AreEqual("Finished serializing System.Collections.Generic.Dictionary`2[System.String,System.String]. Path 'StringDictionary'.", traceWriter.TraceRecords[8].Message); Assert.AreEqual("Finished serializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path ''.", traceWriter.TraceRecords[9].Message); + + Assert.IsFalse(traceWriter.TraceRecords.Any(r => r.Level == TraceLevel.Verbose)); } [Test] @@ -208,6 +278,8 @@ Newtonsoft.Json Error: 0 : Error! Assert.AreEqual("Started deserializing System.Collections.Generic.IDictionary`2[System.String,System.String]. Path 'StringDictionary.1', line 19, position 9.", traceWriter.TraceRecords[8].Message); Assert.AreEqual("Finished deserializing System.Collections.Generic.IDictionary`2[System.String,System.String]. Path 'StringDictionary', line 22, position 4.", traceWriter.TraceRecords[9].Message); Assert.AreEqual("Finished deserializing Newtonsoft.Json.Tests.Serialization.TraceTestObject. Path '', line 23, position 2.", traceWriter.TraceRecords[10].Message); + + Assert.IsFalse(traceWriter.TraceRecords.Any(r => r.Level == TraceLevel.Verbose)); } [Test] @@ -644,6 +716,239 @@ Newtonsoft.Json Error: 0 : Error! Assert.AreEqual(27, deserialized.Age); Assert.AreEqual(23, deserialized.FavoriteNumber); } + +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) + [Test] + public void TraceJsonWriterTest() + { + StringWriter sw = new StringWriter(CultureInfo.InvariantCulture); + JsonTextWriter w = new JsonTextWriter(sw); + TraceJsonWriter traceWriter = new TraceJsonWriter(w); + + traceWriter.WriteStartObject(); + traceWriter.WritePropertyName("Array"); + traceWriter.WriteStartArray(); + traceWriter.WriteValue("String!"); + traceWriter.WriteValue(new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)); + traceWriter.WriteValue(new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(2))); + traceWriter.WriteValue(1.1f); + traceWriter.WriteValue(1.1d); + traceWriter.WriteValue(1.1m); + traceWriter.WriteValue(1); + traceWriter.WriteValue((char)'!'); + traceWriter.WriteValue((short)1); + traceWriter.WriteValue((ushort)1); + traceWriter.WriteValue((int)1); + traceWriter.WriteValue((uint)1); + traceWriter.WriteValue((sbyte)1); + traceWriter.WriteValue((byte)1); + traceWriter.WriteValue((long)1); + traceWriter.WriteValue((ulong)1); + traceWriter.WriteValue((bool)true); + + traceWriter.WriteValue((DateTime?)new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc)); + traceWriter.WriteValue((DateTimeOffset?)new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.FromHours(2))); + traceWriter.WriteValue((float?)1.1f); + traceWriter.WriteValue((double?)1.1d); + traceWriter.WriteValue((decimal?)1.1m); + traceWriter.WriteValue((int?)1); + traceWriter.WriteValue((char?)'!'); + traceWriter.WriteValue((short?)1); + traceWriter.WriteValue((ushort?)1); + traceWriter.WriteValue((int?)1); + traceWriter.WriteValue((uint?)1); + traceWriter.WriteValue((sbyte?)1); + traceWriter.WriteValue((byte?)1); + traceWriter.WriteValue((long?)1); + traceWriter.WriteValue((ulong?)1); + traceWriter.WriteValue((bool?)true); + traceWriter.WriteValue(BigInteger.Parse("9999999990000000000000000000000000000000000")); + + traceWriter.WriteValue((object)true); + traceWriter.WriteValue(TimeSpan.FromMinutes(1)); + traceWriter.WriteValue(Guid.Empty); + traceWriter.WriteValue(new Uri("http://www.google.com/")); + traceWriter.WriteValue(Encoding.UTF8.GetBytes("String!")); + traceWriter.WriteRawValue("[1],"); + traceWriter.WriteRaw("[1]"); + traceWriter.WriteNull(); + traceWriter.WriteUndefined(); + traceWriter.WriteStartConstructor("ctor"); + traceWriter.WriteValue(1); + traceWriter.WriteEndConstructor(); + traceWriter.WriteComment("A comment"); + traceWriter.WriteWhitespace(" "); + traceWriter.WriteEnd(); + traceWriter.WriteEndObject(); + traceWriter.Flush(); + traceWriter.Close(); + + Console.WriteLine(traceWriter.GetJson()); + + Assert.AreEqual(@"{ + ""Array"": [ + ""String!"", + ""2000-12-12T12:12:12Z"", + ""2000-12-12T12:12:12+02:00"", + 1.1, + 1.1, + 1.1, + 1, + ""!"", + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + true, + ""2000-12-12T12:12:12Z"", + ""2000-12-12T12:12:12+02:00"", + 1.1, + 1.1, + 1.1, + 1, + ""!"", + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + true, + 9999999990000000000000000000000000000000000, + true, + true, + ""00:01:00"", + ""00000000-0000-0000-0000-000000000000"", + ""http://www.google.com/"", + ""U3RyaW5nIQ=="", + [1],[1],[1], + null, + undefined, + new ctor( + 1 + ) + /*A comment*/ + ] +}", traceWriter.GetJson()); + } + + [Test] + public void TraceJsonReaderTest() + { + string json = @"{ + ""Array"": [ + ""String!"", + ""2000-12-12T12:12:12Z"", + ""2000-12-12T12:12:12Z"", + ""2000-12-12T12:12:12+00:00"", + ""U3RyaW5nIQ=="", + 1, + 1.1, + 9999999990000000000000000000000000000000000, + null, + undefined, + new ctor( + 1 + ) + /*A comment*/ + ] +}"; + + StringReader sw = new StringReader(json); + JsonTextReader w = new JsonTextReader(sw); + TraceJsonReader traceReader = new TraceJsonReader(w); + + traceReader.Read(); + Assert.AreEqual(JsonToken.StartObject, traceReader.TokenType); + + traceReader.Read(); + Assert.AreEqual(JsonToken.PropertyName, traceReader.TokenType); + Assert.AreEqual("Array", traceReader.Value); + + traceReader.Read(); + Assert.AreEqual(JsonToken.StartArray, traceReader.TokenType); + Assert.AreEqual(null, traceReader.Value); + + traceReader.ReadAsString(); + Assert.AreEqual(JsonToken.String, traceReader.TokenType); + Assert.AreEqual('"', traceReader.QuoteChar); + Assert.AreEqual("String!", traceReader.Value); + + // for great code coverage justice! + traceReader.QuoteChar = '\''; + Assert.AreEqual('\'', traceReader.QuoteChar); + + traceReader.ReadAsString(); + Assert.AreEqual(JsonToken.String, traceReader.TokenType); + Assert.AreEqual("2000-12-12T12:12:12Z", traceReader.Value); + + traceReader.ReadAsDateTime(); + Assert.AreEqual(JsonToken.Date, traceReader.TokenType); + Assert.AreEqual(new DateTime(2000, 12, 12, 12, 12, 12, DateTimeKind.Utc), traceReader.Value); + + traceReader.ReadAsDateTimeOffset(); + Assert.AreEqual(JsonToken.Date, traceReader.TokenType); + Assert.AreEqual(new DateTimeOffset(2000, 12, 12, 12, 12, 12, TimeSpan.Zero), traceReader.Value); + + traceReader.ReadAsBytes(); + Assert.AreEqual(JsonToken.Bytes, traceReader.TokenType); + Assert.AreEqual(Encoding.UTF8.GetBytes("String!"), traceReader.Value); + + traceReader.ReadAsInt32(); + Assert.AreEqual(JsonToken.Integer, traceReader.TokenType); + Assert.AreEqual(1, traceReader.Value); + + traceReader.ReadAsDecimal(); + Assert.AreEqual(JsonToken.Float, traceReader.TokenType); + Assert.AreEqual(1.1m, traceReader.Value); + + traceReader.Read(); + Assert.AreEqual(JsonToken.Integer, traceReader.TokenType); + Assert.AreEqual(typeof(BigInteger), traceReader.ValueType); + Assert.AreEqual(BigInteger.Parse("9999999990000000000000000000000000000000000"), traceReader.Value); + + traceReader.Read(); + Assert.AreEqual(JsonToken.Null, traceReader.TokenType); + + traceReader.Read(); + Assert.AreEqual(JsonToken.Undefined, traceReader.TokenType); + + traceReader.Read(); + Assert.AreEqual(JsonToken.StartConstructor, traceReader.TokenType); + + traceReader.Read(); + Assert.AreEqual(JsonToken.Integer, traceReader.TokenType); + Assert.AreEqual(1, traceReader.Value); + + traceReader.Read(); + Assert.AreEqual(JsonToken.EndConstructor, traceReader.TokenType); + + traceReader.Read(); + Assert.AreEqual(JsonToken.Comment, traceReader.TokenType); + Assert.AreEqual("A comment", traceReader.Value); + + traceReader.Read(); + Assert.AreEqual(JsonToken.EndArray, traceReader.TokenType); + + traceReader.Read(); + Assert.AreEqual(JsonToken.EndObject, traceReader.TokenType); + + Assert.IsFalse(traceReader.Read()); + + traceReader.Close(); + + Console.WriteLine(traceReader.GetJson()); + + Assert.AreEqual(json, traceReader.GetJson()); + } +#endif } public class TraceRecord diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs index b6dd8c95..381aa1e2 100644 --- a/Src/Newtonsoft.Json/JsonSerializer.cs +++ b/Src/Newtonsoft.Json/JsonSerializer.cs @@ -25,6 +25,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Runtime.Serialization.Formatters; @@ -702,8 +703,15 @@ namespace Newtonsoft.Json reader.MaxDepth = _maxDepth; } + TraceJsonReader traceJsonReader = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + ? new TraceJsonReader(reader) + : null; + JsonSerializerInternalReader serializerReader = new JsonSerializerInternalReader(this); - object value = serializerReader.Deserialize(reader, objectType, CheckAdditionalContent); + object value = serializerReader.Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent); + + if (traceJsonReader != null) + TraceWriter.Trace(TraceLevel.Verbose, "Deserialized JSON: " + Environment.NewLine + traceJsonReader.GetJson(), null); // reset reader back to previous options if (previousCulture != null) @@ -828,8 +836,15 @@ namespace Newtonsoft.Json jsonWriter.DateFormatString = _dateFormatString; } + TraceJsonWriter traceJsonWriter = (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) + ? new TraceJsonWriter(jsonWriter) + : null; + JsonSerializerInternalWriter serializerWriter = new JsonSerializerInternalWriter(this); - serializerWriter.Serialize(jsonWriter, value, objectType); + serializerWriter.Serialize(traceJsonWriter ?? jsonWriter, value, objectType); + + if (traceJsonWriter != null) + TraceWriter.Trace(TraceLevel.Verbose, "Serialized JSON: " + Environment.NewLine + traceJsonWriter.GetJson(), null); // reset writer back to previous options if (previousFormatting != null) diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs index 465f9705..ec2e96dc 100644 --- a/Src/Newtonsoft.Json/JsonWriter.cs +++ b/Src/Newtonsoft.Json/JsonWriter.cs @@ -432,7 +432,7 @@ namespace Newtonsoft.Json /// The to read the token from. public void WriteToken(JsonReader reader) { - WriteToken(reader, true); + WriteToken(reader, true, true); } /// @@ -444,6 +444,11 @@ namespace Newtonsoft.Json { ValidationUtils.ArgumentNotNull(reader, "reader"); + WriteToken(reader, writeChildren, true); + } + + internal void WriteToken(JsonReader reader, bool writeChildren, bool writeDateConstructorAsDate) + { int initialDepth; if (reader.TokenType == JsonToken.None) @@ -453,10 +458,10 @@ namespace Newtonsoft.Json else initialDepth = reader.Depth; - WriteToken(reader, initialDepth, writeChildren); + WriteToken(reader, initialDepth, writeChildren, writeDateConstructorAsDate); } - internal void WriteToken(JsonReader reader, int initialDepth, bool writeChildren) + internal void WriteToken(JsonReader reader, int initialDepth, bool writeChildren, bool writeDateConstructorAsDate) { do { @@ -474,7 +479,7 @@ namespace Newtonsoft.Json case JsonToken.StartConstructor: string constructorName = reader.Value.ToString(); // write a JValue date when the constructor is for a date - if (string.Equals(constructorName, "Date", StringComparison.Ordinal)) + if (writeDateConstructorAsDate && string.Equals(constructorName, "Date", StringComparison.Ordinal)) WriteConstructorDate(reader); else WriteStartConstructor(reader.Value.ToString()); @@ -486,7 +491,16 @@ namespace Newtonsoft.Json WriteComment((reader.Value != null) ? reader.Value.ToString() : null); break; case JsonToken.Integer: - WriteValue(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture)); +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) + if (reader.Value is BigInteger) + { + WriteValue((BigInteger)reader.Value); + } + else +#endif + { + WriteValue(Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture)); + } break; case JsonToken.Float: object value = reader.Value; diff --git a/Src/Newtonsoft.Json/Linq/JToken.cs b/Src/Newtonsoft.Json/Linq/JToken.cs index 2e826ac4..e6a36420 100644 --- a/Src/Newtonsoft.Json/Linq/JToken.cs +++ b/Src/Newtonsoft.Json/Linq/JToken.cs @@ -1603,90 +1603,93 @@ namespace Newtonsoft.Json.Linq /// The new object created from the JSON value. public object ToObject(Type objectType) { - PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(objectType); - - switch (typeCode) + if (JsonConvert.DefaultSettings == null) { - case PrimitiveTypeCode.BooleanNullable: - return (bool?) this; - case PrimitiveTypeCode.Boolean: - return (bool) this; - case PrimitiveTypeCode.CharNullable: - return (char?) this; - case PrimitiveTypeCode.Char: - return (char) this; - case PrimitiveTypeCode.SByte: - return (sbyte?) this; - case PrimitiveTypeCode.SByteNullable: - return (sbyte) this; - case PrimitiveTypeCode.ByteNullable: - return (byte?) this; - case PrimitiveTypeCode.Byte: - return (byte) this; - case PrimitiveTypeCode.Int16Nullable: - return (short?) this; - case PrimitiveTypeCode.Int16: - return (short) this; - case PrimitiveTypeCode.UInt16Nullable: - return (ushort?) this; - case PrimitiveTypeCode.UInt16: - return (ushort) this; - case PrimitiveTypeCode.Int32Nullable: - return (int?) this; - case PrimitiveTypeCode.Int32: - return (int) this; - case PrimitiveTypeCode.UInt32Nullable: - return (uint?) this; - case PrimitiveTypeCode.UInt32: - return (uint) this; - case PrimitiveTypeCode.Int64Nullable: - return (long?) this; - case PrimitiveTypeCode.Int64: - return (long) this; - case PrimitiveTypeCode.UInt64Nullable: - return (ulong?) this; - case PrimitiveTypeCode.UInt64: - return (ulong) this; - case PrimitiveTypeCode.SingleNullable: - return (float?) this; - case PrimitiveTypeCode.Single: - return (float) this; - case PrimitiveTypeCode.DoubleNullable: - return (double?) this; - case PrimitiveTypeCode.Double: - return (double) this; - case PrimitiveTypeCode.DecimalNullable: - return (decimal?) this; - case PrimitiveTypeCode.Decimal: - return (decimal) this; - case PrimitiveTypeCode.DateTimeNullable: - return (DateTime?) this; - case PrimitiveTypeCode.DateTime: - return (DateTime) this; + PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(objectType); + + switch (typeCode) + { + case PrimitiveTypeCode.BooleanNullable: + return (bool?)this; + case PrimitiveTypeCode.Boolean: + return (bool)this; + case PrimitiveTypeCode.CharNullable: + return (char?)this; + case PrimitiveTypeCode.Char: + return (char)this; + case PrimitiveTypeCode.SByte: + return (sbyte?)this; + case PrimitiveTypeCode.SByteNullable: + return (sbyte)this; + case PrimitiveTypeCode.ByteNullable: + return (byte?)this; + case PrimitiveTypeCode.Byte: + return (byte)this; + case PrimitiveTypeCode.Int16Nullable: + return (short?)this; + case PrimitiveTypeCode.Int16: + return (short)this; + case PrimitiveTypeCode.UInt16Nullable: + return (ushort?)this; + case PrimitiveTypeCode.UInt16: + return (ushort)this; + case PrimitiveTypeCode.Int32Nullable: + return (int?)this; + case PrimitiveTypeCode.Int32: + return (int)this; + case PrimitiveTypeCode.UInt32Nullable: + return (uint?)this; + case PrimitiveTypeCode.UInt32: + return (uint)this; + case PrimitiveTypeCode.Int64Nullable: + return (long?)this; + case PrimitiveTypeCode.Int64: + return (long)this; + case PrimitiveTypeCode.UInt64Nullable: + return (ulong?)this; + case PrimitiveTypeCode.UInt64: + return (ulong)this; + case PrimitiveTypeCode.SingleNullable: + return (float?)this; + case PrimitiveTypeCode.Single: + return (float)this; + case PrimitiveTypeCode.DoubleNullable: + return (double?)this; + case PrimitiveTypeCode.Double: + return (double)this; + case PrimitiveTypeCode.DecimalNullable: + return (decimal?)this; + case PrimitiveTypeCode.Decimal: + return (decimal)this; + case PrimitiveTypeCode.DateTimeNullable: + return (DateTime?)this; + case PrimitiveTypeCode.DateTime: + return (DateTime)this; #if !NET20 - case PrimitiveTypeCode.DateTimeOffsetNullable: - return (DateTimeOffset?) this; - case PrimitiveTypeCode.DateTimeOffset: - return (DateTimeOffset) this; + case PrimitiveTypeCode.DateTimeOffsetNullable: + return (DateTimeOffset?)this; + case PrimitiveTypeCode.DateTimeOffset: + return (DateTimeOffset)this; #endif - case PrimitiveTypeCode.String: - return (string) this; - case PrimitiveTypeCode.GuidNullable: - return (Guid?) this; - case PrimitiveTypeCode.Guid: - return (Guid) this; - case PrimitiveTypeCode.Uri: - return (Uri) this; - case PrimitiveTypeCode.TimeSpanNullable: - return (TimeSpan?)this; - case PrimitiveTypeCode.TimeSpan: - return (TimeSpan)this; + case PrimitiveTypeCode.String: + return (string)this; + case PrimitiveTypeCode.GuidNullable: + return (Guid?)this; + case PrimitiveTypeCode.Guid: + return (Guid)this; + case PrimitiveTypeCode.Uri: + return (Uri)this; + case PrimitiveTypeCode.TimeSpanNullable: + return (TimeSpan?)this; + case PrimitiveTypeCode.TimeSpan: + return (TimeSpan)this; #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE) - case PrimitiveTypeCode.BigIntegerNullable: - return ToBigIntegerNullable(this); - case PrimitiveTypeCode.BigInteger: - return ToBigInteger(this); + case PrimitiveTypeCode.BigIntegerNullable: + return ToBigIntegerNullable(this); + case PrimitiveTypeCode.BigInteger: + return ToBigInteger(this); #endif + } } return ToObject(objectType, JsonSerializer.CreateDefault()); diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj index 901294ea..99649409 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj @@ -113,6 +113,8 @@ + + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj index 703220c3..8767f452 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net35.csproj @@ -124,6 +124,8 @@ + + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net40.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net40.csproj index 8371f371..943b43de 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net40.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net40.csproj @@ -124,6 +124,8 @@ + + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Portable.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Portable.csproj index 8ae0275a..20268cd6 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Portable.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Portable.csproj @@ -183,6 +183,8 @@ + + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Portable40.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Portable40.csproj index b5744d64..547fe933 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Portable40.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Portable40.csproj @@ -183,6 +183,8 @@ + + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj index 304e1bc8..efa64569 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj @@ -184,6 +184,8 @@ + + diff --git a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs index c4a69234..b5bf5d75 100644 --- a/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs +++ b/Src/Newtonsoft.Json/Properties/AssemblyInfo.cs @@ -92,6 +92,6 @@ using System.Security; // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("4.5.0.0")] -[assembly: AssemblyFileVersion("5.0.4.16105")] +[assembly: AssemblyFileVersion("5.0.5.16119")] [assembly: CLSCompliant(true)] diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs index 76f19463..93e2b5c2 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs @@ -229,7 +229,7 @@ namespace Newtonsoft.Json.Serialization writer.WriteStartObject(); if (reader.TokenType == JsonToken.PropertyName) - writer.WriteToken(reader, reader.Depth - 1, true); + writer.WriteToken(reader, reader.Depth - 1, true, true); else writer.WriteEndObject(); diff --git a/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs b/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs new file mode 100644 index 00000000..b126dafb --- /dev/null +++ b/Src/Newtonsoft.Json/Serialization/TraceJsonReader.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Text; + +namespace Newtonsoft.Json.Serialization +{ + internal class TraceJsonReader : JsonReader, IJsonLineInfo + { + private readonly JsonReader _innerReader; + private readonly JsonTextWriter _textWriter; + private readonly StringWriter _sw; + + public TraceJsonReader(JsonReader innerReader) + { + _innerReader = innerReader; + + _sw = new StringWriter(CultureInfo.InvariantCulture); + _textWriter = new JsonTextWriter(_sw); + _textWriter.Formatting = Formatting.Indented; + } + + public string GetJson() + { + return _sw.ToString(); + } + + public override bool Read() + { + var value = _innerReader.Read(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } + + public override int? ReadAsInt32() + { + var value = _innerReader.ReadAsInt32(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } + + public override string ReadAsString() + { + var value = _innerReader.ReadAsString(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } + + public override byte[] ReadAsBytes() + { + var value = _innerReader.ReadAsBytes(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } + + public override decimal? ReadAsDecimal() + { + var value = _innerReader.ReadAsDecimal(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } + + public override DateTime? ReadAsDateTime() + { + var value = _innerReader.ReadAsDateTime(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } + +#if !NET20 + public override DateTimeOffset? ReadAsDateTimeOffset() + { + var value = _innerReader.ReadAsDateTimeOffset(); + _textWriter.WriteToken(_innerReader, false, false); + return value; + } +#endif + + public override int Depth + { + get { return _innerReader.Depth; } + } + + public override string Path + { + get { return _innerReader.Path; } + } + + public override char QuoteChar + { + get { return _innerReader.QuoteChar; } + protected internal set { _innerReader.QuoteChar = value; } + } + + public override JsonToken TokenType + { + get { return _innerReader.TokenType; } + } + + public override object Value + { + get { return _innerReader.Value; } + } + + public override Type ValueType + { + get { return _innerReader.ValueType; } + } + + public override void Close() + { + _innerReader.Close(); + } + + bool IJsonLineInfo.HasLineInfo() + { + IJsonLineInfo lineInfo = _innerReader as IJsonLineInfo; + return lineInfo != null && lineInfo.HasLineInfo(); + } + + int IJsonLineInfo.LineNumber + { + get + { + IJsonLineInfo lineInfo = _innerReader as IJsonLineInfo; + return (lineInfo != null) ? lineInfo.LineNumber : 0; + } + } + + int IJsonLineInfo.LinePosition + { + get + { + IJsonLineInfo lineInfo = _innerReader as IJsonLineInfo; + return (lineInfo != null) ? lineInfo.LinePosition : 0; + } + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/TraceJsonWriter.cs b/Src/Newtonsoft.Json/Serialization/TraceJsonWriter.cs new file mode 100644 index 00000000..265103b8 --- /dev/null +++ b/Src/Newtonsoft.Json/Serialization/TraceJsonWriter.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) +using System.Numerics; +#endif +using System.Text; + +namespace Newtonsoft.Json.Serialization +{ + internal class TraceJsonWriter : JsonWriter + { + private readonly JsonWriter _innerWriter; + private readonly JsonTextWriter _textWriter; + private readonly StringWriter _sw; + + public TraceJsonWriter(JsonWriter innerWriter) + { + _innerWriter = innerWriter; + + _sw = new StringWriter(CultureInfo.InvariantCulture); + _textWriter = new JsonTextWriter(_sw); + _textWriter.Formatting = Formatting.Indented; + _textWriter.Culture = innerWriter.Culture; + _textWriter.DateFormatHandling = innerWriter.DateFormatHandling; + _textWriter.DateFormatString = innerWriter.DateFormatString; + _textWriter.DateTimeZoneHandling = innerWriter.DateTimeZoneHandling; + _textWriter.FloatFormatHandling = innerWriter.FloatFormatHandling; + } + + public string GetJson() + { + return _sw.ToString(); + } + + public override void WriteValue(decimal value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(bool value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(byte value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(byte? value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(char value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(byte[] value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(DateTime value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + +#if !NET20 + public override void WriteValue(DateTimeOffset value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } +#endif + + public override void WriteValue(double value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteUndefined() + { + _textWriter.WriteUndefined(); + _innerWriter.WriteUndefined(); + base.WriteUndefined(); + } + + public override void WriteNull() + { + _textWriter.WriteNull(); + _innerWriter.WriteNull(); + base.WriteUndefined(); + } + + public override void WriteValue(float value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(Guid value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(int value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(long value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(object value) + { +#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE || PORTABLE40) + if (value is BigInteger) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + InternalWriteValue(JsonToken.Integer); + } + else +#endif + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + } + + public override void WriteValue(sbyte value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(short value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(string value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(TimeSpan value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(uint value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(ulong value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(Uri value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteValue(ushort value) + { + _textWriter.WriteValue(value); + _innerWriter.WriteValue(value); + base.WriteValue(value); + } + + public override void WriteWhitespace(string ws) + { + _textWriter.WriteWhitespace(ws); + _innerWriter.WriteWhitespace(ws); + base.WriteWhitespace(ws); + } + + //protected override void WriteValueDelimiter() + //{ + // _textWriter.WriteValueDelimiter(); + // _innerWriter.WriteValueDelimiter(); + // base.WriteValueDelimiter(); + //} + + //protected override void WriteIndent() + //{ + // base.WriteIndent(); + //} + + public override void WriteComment(string text) + { + _textWriter.WriteComment(text); + _innerWriter.WriteComment(text); + base.WriteComment(text); + } + + //public override void WriteEnd() + //{ + // _textWriter.WriteEnd(); + // _innerWriter.WriteEnd(); + // base.WriteEnd(); + //} + + //protected override void WriteEnd(JsonToken token) + //{ + // base.WriteEnd(token); + //} + + public override void WriteStartArray() + { + _textWriter.WriteStartArray(); + _innerWriter.WriteStartArray(); + base.WriteStartArray(); + } + + public override void WriteEndArray() + { + _textWriter.WriteEndArray(); + _innerWriter.WriteEndArray(); + base.WriteEndArray(); + } + + public override void WriteStartConstructor(string name) + { + _textWriter.WriteStartConstructor(name); + _innerWriter.WriteStartConstructor(name); + base.WriteStartConstructor(name); + } + + public override void WriteEndConstructor() + { + _textWriter.WriteEndConstructor(); + _innerWriter.WriteEndConstructor(); + base.WriteEndConstructor(); + } + + public override void WritePropertyName(string name) + { + _textWriter.WritePropertyName(name); + _innerWriter.WritePropertyName(name); + base.WritePropertyName(name); + } + + public override void WritePropertyName(string name, bool escape) + { + _textWriter.WritePropertyName(name, escape); + _innerWriter.WritePropertyName(name, escape); + + // method with escape will error + base.WritePropertyName(name); + } + + public override void WriteStartObject() + { + _textWriter.WriteStartObject(); + _innerWriter.WriteStartObject(); + base.WriteStartObject(); + } + + public override void WriteEndObject() + { + _textWriter.WriteEndObject(); + _innerWriter.WriteEndObject(); + base.WriteEndObject(); + } + + public override void WriteRaw(string json) + { + _textWriter.WriteRaw(json); + _innerWriter.WriteRaw(json); + base.WriteRaw(json); + } + + public override void WriteRawValue(string json) + { + _textWriter.WriteRawValue(json); + _innerWriter.WriteRawValue(json); + base.WriteRawValue(json); + } + + //protected override void WriteIndentSpace() + //{ + // _textWriter.WriteIndentSpace(); + // _innerWriter.WriteIndentSpace(); + // base.WriteIndentSpace(); + //} + + public override void Close() + { + _textWriter.Close(); + _innerWriter.Close(); + base.Close(); + } + + public override void Flush() + { + _textWriter.Flush(); + _innerWriter.Flush(); + } + } +} \ No newline at end of file